From gitlab at gitlab.haskell.org Wed Apr 1 04:53:27 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Wed, 01 Apr 2020 00:53:27 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] 10 commits: Require GHC 8.8 as the minimum compiler for bootstrapping Message-ID: <5e841e473ca29_6167e0e2c942072665@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 2310cffd by Josh Meredith at 2020-04-01T00:53:23-04:00 Implement extensible interface files - - - - - f99f30d9 by Josh Meredith at 2020-04-01T00:53:23-04:00 Change expected stdout for hi file Docs tests - - - - - 51bf86fb by Josh Meredith at 2020-04-01T00:53:23-04:00 Add comment subtitle section for BinData - - - - - cb00cf1f by Josh Meredith at 2020-04-01T00:53:23-04:00 Add some discussion about extensible interfaces to extending_ghc.rst - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Types/Unique/Supply.hs - compiler/main/SysTools/Process.hs - compiler/main/SysTools/Terminal.hs - compiler/typecheck/TcRnTypes.hs - compiler/typecheck/TcSMonad.hs - compiler/utils/Binary.hs - compiler/utils/IOEnv.hs - configure.ac - docs/users_guide/extending_ghc.rst - hadrian/cabal.project - hadrian/src/Hadrian/Utilities.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Builders/Ghc.hs - libraries/base/Control/Monad/ST/Lazy/Imp.hs - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/ST.hs - libraries/base/Text/ParserCombinators/ReadPrec.hs - libraries/ghci/GHCi/TH.hs - libraries/integer-gmp/changelog.md - libraries/integer-gmp/integer-gmp.cabal The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f714f99a87c1c14e09c7f143a4478d34e6f2d73...cb00cf1f4b77bcc0a5376d427e97b7d98ed52090 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f714f99a87c1c14e09c7f143a4478d34e6f2d73...cb00cf1f4b77bcc0a5376d427e97b7d98ed52090 You're receiving 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 1 05:20:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 01:20:05 -0400 Subject: [Git][ghc/ghc][master] Clean up "Eta reduction for data families" Notes Message-ID: <5e842485d9c5e_6167116c28dc2073195@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/TyCon.hs - compiler/typecheck/TcDeriv.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcSplice.hs Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -245,7 +245,7 @@ ppr_co_ax_branch ppr_rhs fam_tc branch -- Eta-expand LHS and RHS types, because sometimes data family -- instances are eta-reduced. - -- See Note [Eta reduction for data families] in GHC.Core.FamInstEnv. + -- See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. (ee_tvs, ee_lhs, ee_rhs) = etaExpandCoAxBranch branch pp_lhs = pprIfaceTypeApp topPrec (toIfaceTyCon fam_tc) ===================================== compiler/GHC/Core/Coercion/Axiom.hs ===================================== @@ -235,7 +235,7 @@ data CoAxBranch , cab_tvs :: [TyVar] -- Bound type variables; not necessarily fresh , cab_eta_tvs :: [TyVar] -- Eta-reduced tyvars -- See Note [CoAxBranch type variables] - -- cab_tvs and cab_lhs may be eta-reduded; see + -- cab_tvs and cab_lhs may be eta-reduced; see -- Note [Eta reduction for data families] , cab_cvs :: [CoVar] -- Bound coercion variables -- Always empty, for now. @@ -443,9 +443,13 @@ looked like (See #9692, #14179, and #15845 for examples of what can go wrong if we don't eta-expand when showing things to the user.) -(See also Note [Newtype eta] in GHC.Core.TyCon. This is notionally separate -and deals with the axiom connecting a newtype with its representation -type; but it too is eta-reduced.) +See also: + +* Note [Newtype eta] in GHC.Core.TyCon. This is notionally separate + and deals with the axiom connecting a newtype with its representation + type; but it too is eta-reduced. +* Note [Implementing eta reduction for data families] in TcInstDcls. This + describes the implementation details of this eta reduction happen. -} instance Eq (CoAxiom br) where ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -118,6 +118,7 @@ data FamInst -- See Note [FamInsts and CoAxioms] , fi_tys :: [Type] -- The LHS type patterns -- May be eta-reduced; see Note [Eta reduction for data families] + -- in GHC.Core.Coercion.Axiom , fi_rhs :: Type -- the RHS, with its freshened vars } @@ -132,7 +133,8 @@ Note [Arity of data families] Data family instances might legitimately be over- or under-saturated. Under-saturation has two potential causes: - U1) Eta reduction. See Note [Eta reduction for data families]. + U1) Eta reduction. See Note [Eta reduction for data families] in + GHC.Core.Coercion.Axiom. U2) When the user has specified a return kind instead of written out patterns. Example: @@ -160,8 +162,8 @@ Over-saturation is also possible: However, we require that any over-saturation is eta-reducible. That is, we require that any extra patterns be bare unrepeated type variables; - see Note [Eta reduction for data families]. Accordingly, the FamInst - is never over-saturated. + see Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. + Accordingly, the FamInst is never over-saturated. Why can we allow such flexibility for data families but not for type families? Because data families can be decomposed -- that is, they are generative and @@ -335,7 +337,7 @@ Then we get a data type for each instance, and an axiom: axiom ax8 a :: T Bool [a] ~ TBoolList a These two axioms for T, one with one pattern, one with two; -see Note [Eta reduction for data families] +see Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom Note [FamInstEnv determinism] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -479,7 +481,7 @@ irrelevant (clause 1 of compatible) or benign (clause 2 of compatible). Note [Compatibility of eta-reduced axioms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In newtype instances of data families we eta-reduce the axioms, -See Note [Eta reduction for data families] in GHC.Core.FamInstEnv. This means that +See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. This means that we sometimes need to test compatibility of two axioms that were eta-reduced to different degrees, e.g.: @@ -1057,7 +1059,7 @@ We handle data families and type families separately here: * For data family instances, though, we need to re-split for each instance, because the breakdown might be different for each instance. Why? Because of eta reduction; see - Note [Eta reduction for data families]. + Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. -} -- checks if one LHS is dominated by a list of other branches ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -240,7 +240,7 @@ See also Note [Wrappers for data instance tycons] in GHC.Types.Id.Make DataFamInstTyCon T [Int] ax_ti * The axiom ax_ti may be eta-reduced; see - Note [Eta reduction for data families] in GHC.Core.FamInstEnv + Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom * Data family instances may have a different arity than the data family. See Note [Arity of data families] in GHC.Core.FamInstEnv @@ -1100,8 +1100,9 @@ data AlgTyConFlav -- and R:T is the representation TyCon (ie this one) -- and a,b,c are the tyConTyVars of this TyCon -- - -- BUT may be eta-reduced; see FamInstEnv - -- Note [Eta reduction for data families] + -- BUT may be eta-reduced; see + -- Note [Eta reduction for data families] in + -- GHC.Core.Coercion.Axiom -- Cached fields of the CoAxiom, but adjusted to -- use the tyConTyVars of this TyCon ===================================== compiler/typecheck/TcDeriv.hs ===================================== @@ -1312,7 +1312,7 @@ write it out return x = MkT [x] ... etc ... -See Note [Eta reduction for data families] in GHC.Core.FamInstEnv +See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom %************************************************************************ %* * ===================================== compiler/typecheck/TcInstDcls.hs ===================================== @@ -667,7 +667,7 @@ tcDataFamInstDecl mb_clsinfo new_or_data -- Eta-reduce the axiom if possible - -- Quite tricky: see Note [Eta-reduction for data families] + -- Quite tricky: see Note [Implementing eta reduction for data families] ; let (eta_pats, eta_tcbs) = eta_reduce fam_tc pats eta_tvs = map binderVar eta_tcbs post_eta_qtvs = filterOut (`elem` eta_tvs) qtvs @@ -761,7 +761,7 @@ tcDataFamInstDecl mb_clsinfo ; return (fam_inst, m_deriv_info) } where eta_reduce :: TyCon -> [Type] -> ([Type], [TyConBinder]) - -- See Note [Eta reduction for data families] in GHC.Core.FamInstEnv + -- See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom -- Splits the incoming patterns into two: the [TyVar] -- are the patterns that can be eta-reduced away. -- e.g. T [a] Int a d c ==> (T [a] Int a, [d,c]) @@ -887,8 +887,8 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. Inst.deeplySkolemise and TcUnify.tcSkolemise Examples in indexed-types/should_compile/T12369 -Note [Eta-reduction for data families] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Implementing eta reduction for data families] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data D :: * -> * -> * -> * -> * @@ -906,7 +906,10 @@ and an axiom to connect them except that we'll eta-reduce the axiom to axiom AxDrep forall a b. D [(a,b]] = Drep a b -There are several fiddly subtleties lurking here + +This is described at some length in Note [Eta reduction for data families] +in GHC.Core.Coercion.Axiom. There are several fiddly subtleties lurking here, +however, so this Note aims to describe these subtleties: * The representation tycon Drep is parameterised over the free variables of the pattern, in no particular order. So there is no ===================================== compiler/typecheck/TcSplice.hs ===================================== @@ -2046,7 +2046,7 @@ reifyFamilyInstance is_poly_tvs (FamInst { fi_flavor = flavor DataFamilyInst rep_tc -> do { let -- eta-expand lhs types, because sometimes data/newtype -- instances are eta-reduced; See #9692 - -- See Note [Eta reduction for data families] in GHC.Core.FamInstEnv + -- See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom (ee_tvs, ee_lhs, _) = etaExpandCoAxBranch branch fam' = reifyName fam dataCons = tyConDataCons rep_tc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9b39f2e6f63ae50cedd96eaf49146de8ed00fbc8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9b39f2e6f63ae50cedd96eaf49146de8ed00fbc8 You're receiving 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 1 05:20:44 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 01:20:44 -0400 Subject: [Git][ghc/ghc][master] Fix the changelog/@since information for hGetContents'/getContents'/readFile' Message-ID: <5e8424aca4d42_6167e0e2c942077322@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 3 changed files: - libraries/base/GHC/IO/Handle/Text.hs - libraries/base/System/IO.hs - libraries/base/changelog.md Changes: ===================================== libraries/base/GHC/IO/Handle/Text.hs ===================================== @@ -466,7 +466,7 @@ getSomeCharacters handle_ at Handle__{..} buf at Buffer{..} = -- | The 'hGetContents'' operation reads all input on the given handle -- before returning it as a 'String' and closing the handle. -- --- @since 4.14.0.0 +-- @since 4.15.0.0 hGetContents' :: Handle -> IO String hGetContents' handle = do ===================================== libraries/base/System/IO.hs ===================================== @@ -312,7 +312,7 @@ getContents = hGetContents stdin -- which is fully read before being returned -- (same as 'hGetContents'' 'stdin'). -- --- @since 4.14.0.0 +-- @since 4.15.0.0 getContents' :: IO String getContents' = hGetContents' stdin @@ -337,7 +337,7 @@ readFile name = openFile name ReadMode >>= hGetContents -- returns the contents of the file as a string. -- The file is fully read before being returned, as with 'getContents''. -- --- @since 4.14.0.0 +-- @since 4.15.0.0 readFile' :: FilePath -> IO String readFile' name = openFile name ReadMode >>= hGetContents' ===================================== libraries/base/changelog.md ===================================== @@ -6,6 +6,9 @@ call, ensuring that the call can be interrupted with `SIGINT` on POSIX systems. + * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: + Strict IO variants of `hGetContents`, `getContents`, and `readFile`. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 @@ -51,9 +54,6 @@ * Add `IsList` instance for `ZipList`. - * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: - Strict IO variants of `hGetContents`, `getContents`, and `readFile`. - ## 4.13.0.0 *July 2019* * Bundled with GHC 8.8.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7627eab5dd882eb6f1567e3ae95c6c770830a5eb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7627eab5dd882eb6f1567e3ae95c6c770830a5eb You're receiving 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 1 05:21:37 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 01:21:37 -0400 Subject: [Git][ghc/ghc][master] Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Message-ID: <5e8424e149f83_61676830044208473c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 14 changed files: - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs - configure.ac - distrib/configure.ac.in - hadrian/cfg/system.config.in - hadrian/src/Rules/Generate.hs - includes/ghc.mk - libraries/ghc-boot/GHC/Platform.hs - libraries/ghc-boot/GHC/Settings.hs - mk/config.mk.in - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/Info.hs ===================================== @@ -206,7 +206,7 @@ mkInfoTableContents dflags ; return (prof_data ++ liveness_data, (std_info, srt_label)) } | HeapRep _ ptrs nonptrs closure_type <- smrep - = do { let layout = packIntsCLit dflags ptrs nonptrs + = do { let layout = packIntsCLit platform ptrs nonptrs ; (prof_lits, prof_data) <- mkProfLits platform prof ; let (srt_label, srt_bitmap) = mkSRTLit dflags info_lbl srt ; (mb_srt_field, mb_layout, extra_bits, ct_data) @@ -238,14 +238,14 @@ mkInfoTableContents dflags -- Layout known (one free var); we use the layout field for offset mk_pieces (Fun arity (ArgSpec fun_type)) srt_label - = do { let extra_bits = packIntsCLit dflags fun_type arity : srt_label + = do { let extra_bits = packIntsCLit platform fun_type arity : srt_label ; return (Nothing, Nothing, extra_bits, []) } mk_pieces (Fun arity (ArgGen arg_bits)) srt_label = do { (liveness_lit, liveness_data) <- mkLivenessBits dflags arg_bits ; let fun_type | null liveness_data = aRG_GEN | otherwise = aRG_GEN_BIG - extra_bits = [ packIntsCLit dflags fun_type arity ] + extra_bits = [ packIntsCLit platform fun_type arity ] ++ (if inlineSRT dflags then [] else [ srt_lit ]) ++ [ liveness_lit, slow_entry ] ; return (Nothing, Nothing, extra_bits, liveness_data) } @@ -259,11 +259,10 @@ mkInfoTableContents dflags mkInfoTableContents _ _ _ = panic "mkInfoTableContents" -- NonInfoTable dealt with earlier -packIntsCLit :: DynFlags -> Int -> Int -> CmmLit -packIntsCLit dflags a b = packHalfWordsCLit dflags +packIntsCLit :: Platform -> Int -> Int -> CmmLit +packIntsCLit platform a b = packHalfWordsCLit platform (toStgHalfWord platform (fromIntegral a)) (toStgHalfWord platform (fromIntegral b)) - where platform = targetPlatform dflags mkSRTLit :: DynFlags ===================================== compiler/GHC/Cmm/Utils.hs ===================================== @@ -225,19 +225,18 @@ mkRODataLits lbl lits mkStgWordCLit :: Platform -> StgWord -> CmmLit mkStgWordCLit platform wd = CmmInt (fromStgWord wd) (wordWidth platform) -packHalfWordsCLit :: DynFlags -> StgHalfWord -> StgHalfWord -> CmmLit +packHalfWordsCLit :: Platform -> StgHalfWord -> StgHalfWord -> CmmLit -- Make a single word literal in which the lower_half_word is -- at the lower address, and the upper_half_word is at the -- higher address -- ToDo: consider using half-word lits instead -- but be careful: that's vulnerable when reversed -packHalfWordsCLit dflags lower_half_word upper_half_word - = if wORDS_BIGENDIAN dflags - then mkWordCLit platform ((l `shiftL` halfWordSizeInBits platform) .|. u) - else mkWordCLit platform (l .|. (u `shiftL` halfWordSizeInBits platform)) +packHalfWordsCLit platform lower_half_word upper_half_word + = case platformByteOrder platform of + BigEndian -> mkWordCLit platform ((l `shiftL` halfWordSizeInBits platform) .|. u) + LittleEndian -> mkWordCLit platform (l .|. (u `shiftL` halfWordSizeInBits platform)) where l = fromStgHalfWord lower_half_word u = fromStgHalfWord upper_half_word - platform = targetPlatform dflags --------------------------------------------------- -- ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -520,41 +520,41 @@ pprStatics dflags = pprStatics' (CmmStaticLit (CmmFloat f W32) : rest) -- odd numbers of floats are padded to a word by mkVirtHeapOffsetsWithPadding | wordWidth platform == W64, CmmStaticLit (CmmInt 0 W32) : rest' <- rest - -> pprLit1 dflags (floatToWord dflags f) : pprStatics' rest' + -> pprLit1 dflags (floatToWord platform f) : pprStatics' rest' -- adjacent floats aren't padded but combined into a single word | wordWidth platform == W64, CmmStaticLit (CmmFloat g W32) : rest' <- rest - -> pprLit1 dflags (floatPairToWord dflags f g) : pprStatics' rest' + -> pprLit1 dflags (floatPairToWord platform f g) : pprStatics' rest' | wordWidth platform == W32 - -> pprLit1 dflags (floatToWord dflags f) : pprStatics' rest + -> pprLit1 dflags (floatToWord platform f) : pprStatics' rest | otherwise -> pprPanic "pprStatics: float" (vcat (map ppr' rest)) where ppr' (CmmStaticLit l) = ppr (cmmLitType platform l) ppr' _other = text "bad static!" (CmmStaticLit (CmmFloat f W64) : rest) - -> map (pprLit1 dflags) (doubleToWords dflags f) ++ pprStatics' rest + -> map (pprLit1 dflags) (doubleToWords platform f) ++ pprStatics' rest (CmmStaticLit (CmmInt i W64) : rest) | wordWidth platform == W32 - -> if wORDS_BIGENDIAN dflags - then pprStatics' (CmmStaticLit (CmmInt q W32) : - CmmStaticLit (CmmInt r W32) : rest) - else pprStatics' (CmmStaticLit (CmmInt r W32) : - CmmStaticLit (CmmInt q W32) : rest) + -> case platformByteOrder platform of + BigEndian -> pprStatics' (CmmStaticLit (CmmInt q W32) : + CmmStaticLit (CmmInt r W32) : rest) + LittleEndian -> pprStatics' (CmmStaticLit (CmmInt r W32) : + CmmStaticLit (CmmInt q W32) : rest) where r = i .&. 0xffffffff q = i `shiftR` 32 (CmmStaticLit (CmmInt a W32) : CmmStaticLit (CmmInt b W32) : rest) | wordWidth platform == W64 - -> if wORDS_BIGENDIAN dflags - then pprStatics' (CmmStaticLit (CmmInt ((shiftL a 32) .|. b) W64) : rest) - else pprStatics' (CmmStaticLit (CmmInt ((shiftL b 32) .|. a) W64) : rest) + -> case platformByteOrder platform of + BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 32) .|. b) W64) : rest) + LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 32) .|. a) W64) : rest) (CmmStaticLit (CmmInt a W16) : CmmStaticLit (CmmInt b W16) : rest) | wordWidth platform == W32 - -> if wORDS_BIGENDIAN dflags - then pprStatics' (CmmStaticLit (CmmInt ((shiftL a 16) .|. b) W32) : rest) - else pprStatics' (CmmStaticLit (CmmInt ((shiftL b 16) .|. a) W32) : rest) + -> case platformByteOrder platform of + BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 16) .|. b) W32) : rest) + LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 16) .|. a) W32) : rest) (CmmStaticLit (CmmInt _ w) : _) | w /= wordWidth platform @@ -1271,8 +1271,8 @@ castFloatToWord32Array = U.castSTUArray castDoubleToWord64Array :: STUArray s Int Double -> ST s (STUArray s Int Word64) castDoubleToWord64Array = U.castSTUArray -floatToWord :: DynFlags -> Rational -> CmmLit -floatToWord dflags r +floatToWord :: Platform -> Rational -> CmmLit +floatToWord platform r = runST (do arr <- newArray_ ((0::Int),0) writeArray arr 0 (fromRational r) @@ -1281,12 +1281,13 @@ floatToWord dflags r return (CmmInt (toInteger w32 `shiftL` wo) (wordWidth platform)) ) where wo | wordWidth platform == W64 - , wORDS_BIGENDIAN dflags = 32 - | otherwise = 0 - platform = targetPlatform dflags + , BigEndian <- platformByteOrder platform + = 32 + | otherwise + = 0 -floatPairToWord :: DynFlags -> Rational -> Rational -> CmmLit -floatPairToWord dflags r1 r2 +floatPairToWord :: Platform -> Rational -> Rational -> CmmLit +floatPairToWord platform r1 r2 = runST (do arr <- newArray_ ((0::Int),1) writeArray arr 0 (fromRational r1) @@ -1297,15 +1298,15 @@ floatPairToWord dflags r1 r2 return (pprWord32Pair w32_1 w32_2) ) where pprWord32Pair w32_1 w32_2 - | wORDS_BIGENDIAN dflags = + | BigEndian <- platformByteOrder platform = CmmInt ((shiftL i1 32) .|. i2) W64 | otherwise = CmmInt ((shiftL i2 32) .|. i1) W64 where i1 = toInteger w32_1 i2 = toInteger w32_2 -doubleToWords :: DynFlags -> Rational -> [CmmLit] -doubleToWords dflags r +doubleToWords :: Platform -> Rational -> [CmmLit] +doubleToWords platform r = runST (do arr <- newArray_ ((0::Int),1) writeArray arr 0 (fromRational r) @@ -1314,8 +1315,6 @@ doubleToWords dflags r return (pprWord64 w64) ) where targetWidth = wordWidth platform - platform = targetPlatform dflags - targetBE = wORDS_BIGENDIAN dflags pprWord64 w64 | targetWidth == W64 = [ CmmInt (toInteger w64) targetWidth ] @@ -1324,9 +1323,9 @@ doubleToWords dflags r , CmmInt (toInteger targetW2) targetWidth ] | otherwise = panic "doubleToWords.pprWord64" - where (targetW1, targetW2) - | targetBE = (wHi, wLo) - | otherwise = (wLo, wHi) + where (targetW1, targetW2) = case platformByteOrder platform of + BigEndian -> (wHi, wLo) + LittleEndian -> (wLo, wHi) wHi = w64 `shiftR` 32 wLo = w64 .&. 0xFFFFffff ===================================== compiler/GHC/Llvm/Types.hs ===================================== @@ -225,26 +225,26 @@ ppPlainName (LMLitVar x ) = ppLit x -- | Print a literal value. No type. ppLit :: LlvmLit -> SDoc -ppLit (LMIntLit i (LMInt 32)) = ppr (fromInteger i :: Int32) -ppLit (LMIntLit i (LMInt 64)) = ppr (fromInteger i :: Int64) -ppLit (LMIntLit i _ ) = ppr ((fromInteger i)::Int) -ppLit (LMFloatLit r LMFloat ) = ppFloat $ narrowFp r -ppLit (LMFloatLit r LMDouble) = ppDouble r -ppLit f@(LMFloatLit _ _) = pprPanic "ppLit" (text "Can't print this float literal: " <> ppr f) -ppLit (LMVectorLit ls ) = char '<' <+> ppCommaJoin ls <+> char '>' -ppLit (LMNullLit _ ) = text "null" --- #11487 was an issue where we passed undef for some arguments --- that were actually live. By chance the registers holding those --- arguments usually happened to have the right values anyways, but --- that was not guaranteed. To find such bugs reliably, we set the --- flag below when validating, which replaces undef literals (at --- common types) with values that are likely to cause a crash or test --- failure. -ppLit (LMUndefLit t ) = sdocWithDynFlags f - where f dflags - | gopt Opt_LlvmFillUndefWithGarbage dflags, - Just lit <- garbageLit t = ppLit lit - | otherwise = text "undef" +ppLit l = sdocWithDynFlags $ \dflags -> case l of + (LMIntLit i (LMInt 32)) -> ppr (fromInteger i :: Int32) + (LMIntLit i (LMInt 64)) -> ppr (fromInteger i :: Int64) + (LMIntLit i _ ) -> ppr ((fromInteger i)::Int) + (LMFloatLit r LMFloat ) -> ppFloat (targetPlatform dflags) $ narrowFp r + (LMFloatLit r LMDouble) -> ppDouble (targetPlatform dflags) r + f@(LMFloatLit _ _) -> pprPanic "ppLit" (text "Can't print this float literal: " <> ppr f) + (LMVectorLit ls ) -> char '<' <+> ppCommaJoin ls <+> char '>' + (LMNullLit _ ) -> text "null" + -- #11487 was an issue where we passed undef for some arguments + -- that were actually live. By chance the registers holding those + -- arguments usually happened to have the right values anyways, but + -- that was not guaranteed. To find such bugs reliably, we set the + -- flag below when validating, which replaces undef literals (at + -- common types) with values that are likely to cause a crash or test + -- failure. + (LMUndefLit t ) + | gopt Opt_LlvmFillUndefWithGarbage dflags + , Just lit <- garbageLit t -> ppLit lit + | otherwise -> text "undef" garbageLit :: LlvmType -> Maybe LlvmLit garbageLit t@(LMInt w) = Just (LMIntLit (0xbbbbbbbbbbbbbbb0 `mod` (2^w)) t) @@ -836,19 +836,20 @@ instance Outputable LlvmCastOp where -- regardless of underlying architecture. -- -- See Note [LLVM Float Types]. -ppDouble :: Double -> SDoc -ppDouble d +ppDouble :: Platform -> Double -> SDoc +ppDouble platform d = let bs = doubleToBytes d hex d' = case showHex d' "" of - [] -> error "dToStr: too few hex digits for float" - [x] -> ['0',x] - [x,y] -> [x,y] - _ -> error "dToStr: too many hex digits for float" + [] -> error "ppDouble: too few hex digits for float" + [x] -> ['0',x] + [x,y] -> [x,y] + _ -> error "ppDouble: too many hex digits for float" - in sdocWithDynFlags (\dflags -> - let fixEndian = if wORDS_BIGENDIAN dflags then id else reverse - str = map toUpper $ concat $ fixEndian $ map hex bs - in text "0x" <> text str) + fixEndian = case platformByteOrder platform of + BigEndian -> id + LittleEndian -> reverse + str = map toUpper $ concat $ fixEndian $ map hex bs + in text "0x" <> text str -- Note [LLVM Float Types] -- ~~~~~~~~~~~~~~~~~~~~~~~ @@ -875,8 +876,8 @@ widenFp :: Float -> Double {-# NOINLINE widenFp #-} widenFp = float2Double -ppFloat :: Float -> SDoc -ppFloat = ppDouble . widenFp +ppFloat :: Platform -> Float -> SDoc +ppFloat platform = ppDouble platform . widenFp -------------------------------------------------------------------------------- ===================================== compiler/GHC/Runtime/Heap/Inspect.hs ===================================== @@ -865,10 +865,9 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 -- This is a bit involved since we allow packing multiple fields -- within a single word. See also -- GHC.StgToCmm.Layout.mkVirtHeapOffsetsWithPadding - dflags <- getDynFlags - let platform = targetPlatform dflags - word_size = platformWordSizeInBytes platform - big_endian = wORDS_BIGENDIAN dflags + platform <- targetPlatform <$> getDynFlags + let word_size = platformWordSizeInBytes platform + endian = platformByteOrder platform size_b = primRepSizeB platform rep -- Align the start offset (eg, 2-byte value should be 2-byte -- aligned). But not more than to a word. The offset calculation @@ -877,7 +876,7 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 !aligned_idx = roundUpTo arr_i (min word_size size_b) !new_arr_i = aligned_idx + size_b ws | size_b < word_size = - [index size_b aligned_idx word_size big_endian] + [index size_b aligned_idx word_size endian] | otherwise = let (q, r) = size_b `quotRem` word_size in ASSERT( r == 0 ) @@ -892,7 +891,7 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 (error "unboxedTupleTerm: no HValue for unboxed tuple") terms -- Extract a sub-word sized field from a word - index item_size_b index_b word_size big_endian = + index item_size_b index_b word_size endian = (word .&. (mask `shiftL` moveBytes)) `shiftR` moveBytes where mask :: Word @@ -903,9 +902,9 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 _ -> panic ("Weird byte-index: " ++ show index_b) (q,r) = index_b `quotRem` word_size word = array!!q - moveBytes = if big_endian - then word_size - (r + item_size_b) * 8 - else r * 8 + moveBytes = case endian of + BigEndian -> word_size - (r + item_size_b) * 8 + LittleEndian -> r * 8 -- | Fast, breadth-first Type reconstruction ===================================== configure.ac ===================================== @@ -952,6 +952,10 @@ else AC_SUBST([Cabal64bit],[False]) fi AC_SUBST(TargetWordSize) + +AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) +AC_SUBST(TargetWordBigEndian) + FP_CHECK_FUNC([WinExec], [@%:@include ], [WinExec("",0)]) ===================================== distrib/configure.ac.in ===================================== @@ -177,6 +177,17 @@ fi TargetWordSize=$ac_cv_sizeof_void_p AC_SUBST(TargetWordSize) +dnl TargetWordBigEndian for settings file +AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) +dnl Check that the toolchain we have is consistent with what the compiler expects +if test "x$TargetWordBigEndian" != "x at TargetWordBigEndian@"; then + AC_MSG_ERROR([This binary distribution produces binaries for a target with + a different byte order than your target toolchain. + Are you sure your toolchain targets the intended target platform + of this compiler?]) +fi +AC_SUBST(TargetWordBigEndian) + # dnl ** how to invoke `ar' and `ranlib' # ===================================== hadrian/cfg/system.config.in ===================================== @@ -146,6 +146,7 @@ settings-llc-command = @SettingsLlcCommand@ settings-opt-command = @SettingsOptCommand@ target-word-size = @TargetWordSize@ +target-word-big-endian = @TargetWordBigEndian@ target-has-gnu-nonexec-stack = @TargetHasGnuNonexecStack@ target-has-ident-directive = @TargetHasIdentDirective@ target-has-subsections-via-symbols = @TargetHasSubsectionsViaSymbols@ ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -301,6 +301,7 @@ generateSettings = do , ("target os", getSetting TargetOsHaskell) , ("target arch", getSetting TargetArchHaskell) , ("target word size", expr $ lookupValueOrError configFile "target-word-size") + , ("target word big endian", expr $ lookupValueOrError configFile "target-word-big-endian") , ("target has GNU nonexec stack", expr $ lookupValueOrError configFile "target-has-gnu-nonexec-stack") , ("target has .ident directive", expr $ lookupValueOrError configFile "target-has-ident-directive") , ("target has subsections via symbols", expr $ lookupValueOrError configFile "target-has-subsections-via-symbols") ===================================== includes/ghc.mk ===================================== @@ -236,6 +236,7 @@ $(includes_SETTINGS) : includes/Makefile | $$(dir $$@)/. @echo ',("target os", "$(HaskellTargetOs)")' >> $@ @echo ',("target arch", "$(HaskellTargetArch)")' >> $@ @echo ',("target word size", "$(TargetWordSize)")' >> $@ + @echo ',("target word big endian", "$(TargetWordBigEndian)")' >> $@ @echo ',("target has GNU nonexec stack", "$(TargetHasGnuNonexecStack)")' >> $@ @echo ',("target has .ident directive", "$(TargetHasIdentDirective)")' >> $@ @echo ',("target has subsections via symbols", "$(TargetHasSubsectionsViaSymbols)")' >> $@ ===================================== libraries/ghc-boot/GHC/Platform.hs ===================================== @@ -12,6 +12,7 @@ module GHC.Platform ( ArmISAExt(..), ArmABI(..), PPC_64ABI(..), + ByteOrder(..), target32Bit, isARM, @@ -38,6 +39,7 @@ where import Prelude -- See Note [Why do we import Prelude here?] import GHC.Read +import GHC.ByteOrder (ByteOrder(..)) import Data.Word import Data.Int @@ -53,19 +55,17 @@ data PlatformMini -- | Contains enough information for the native code generator to emit -- code for this platform. -data Platform - = Platform { - platformMini :: PlatformMini, - -- Word size in bytes (i.e. normally 4 or 8, - -- for 32bit and 64bit platforms respectively) - platformWordSize :: PlatformWordSize, - platformUnregisterised :: Bool, - platformHasGnuNonexecStack :: Bool, - platformHasIdentDirective :: Bool, - platformHasSubsectionsViaSymbols :: Bool, - platformIsCrossCompiling :: Bool - } - deriving (Read, Show, Eq) +data Platform = Platform + { platformMini :: PlatformMini + , platformWordSize :: PlatformWordSize + , platformByteOrder :: ByteOrder + , platformUnregisterised :: Bool + , platformHasGnuNonexecStack :: Bool + , platformHasIdentDirective :: Bool + , platformHasSubsectionsViaSymbols :: Bool + , platformIsCrossCompiling :: Bool + } + deriving (Read, Show, Eq) data PlatformWordSize = PW4 -- ^ A 32-bit platform ===================================== libraries/ghc-boot/GHC/Settings.hs ===================================== @@ -36,6 +36,7 @@ getTargetPlatform settingsFile mySettings = do targetArch <- readSetting "target arch" targetOS <- readSetting "target os" targetWordSize <- readSetting "target word size" + targetWordBigEndian <- getBooleanSetting "target word big endian" targetUnregisterised <- getBooleanSetting "Unregisterised" targetHasGnuNonexecStack <- getBooleanSetting "target has GNU nonexec stack" targetHasIdentDirective <- getBooleanSetting "target has .ident directive" @@ -48,6 +49,7 @@ getTargetPlatform settingsFile mySettings = do , platformMini_os = targetOS } , platformWordSize = targetWordSize + , platformByteOrder = if targetWordBigEndian then BigEndian else LittleEndian , platformUnregisterised = targetUnregisterised , platformHasGnuNonexecStack = targetHasGnuNonexecStack , platformHasIdentDirective = targetHasIdentDirective ===================================== mk/config.mk.in ===================================== @@ -494,6 +494,7 @@ HaskellHostArch = @HaskellHostArch@ HaskellTargetOs = @HaskellTargetOs@ HaskellTargetArch = @HaskellTargetArch@ TargetWordSize = @TargetWordSize@ +TargetWordBigEndian = @TargetWordBigEndian@ TargetHasGnuNonexecStack = @TargetHasGnuNonexecStack@ TargetHasIdentDirective = @TargetHasIdentDirective@ TargetHasSubsectionsViaSymbols = @TargetHasSubsectionsViaSymbols@ ===================================== utils/deriveConstants/Main.hs ===================================== @@ -672,7 +672,6 @@ wanteds os = concat -- Amount of pointer bits used for semi-tagging constructor closures ,constantWord Haskell "TAG_BITS" "TAG_BITS" - ,constantBool Haskell "WORDS_BIGENDIAN" "defined(WORDS_BIGENDIAN)" ,constantBool Haskell "DYNAMIC_BY_DEFAULT" "defined(DYNAMIC_BY_DEFAULT)" ,constantWord Haskell "LDV_SHIFT" "LDV_SHIFT" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0002db1bf436cbd32f97b659a52b1eee4e8b21db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0002db1bf436cbd32f97b659a52b1eee4e8b21db You're receiving 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 1 05:53:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 01:53:05 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Clean up "Eta reduction for data families" Notes Message-ID: <5e842c412ffd2_61676653460209107@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 856b624c by Sebastian Graf at 2020-04-01T01:52:54-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - ecdc6599 by Andreas Klebinger at 2020-04-01T01:52:54-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - 30 changed files: - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/typecheck/TcDeriv.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcSplice.hs - configure.ac - distrib/configure.ac.in - hadrian/cfg/system.config.in - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Builders/Ghc.hs - includes/ghc.mk - libraries/base/GHC/IO/Handle/Text.hs - libraries/base/System/IO.hs - libraries/base/changelog.md - libraries/ghc-boot/GHC/Platform.hs - libraries/ghc-boot/GHC/Settings.hs - mk/config.mk.in - + testsuite/tests/pmcheck/should_compile/T17977.hs - + testsuite/tests/pmcheck/should_compile/T17977b.hs - + testsuite/tests/pmcheck/should_compile/T17977b.stderr - testsuite/tests/pmcheck/should_compile/all.T - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/Info.hs ===================================== @@ -206,7 +206,7 @@ mkInfoTableContents dflags ; return (prof_data ++ liveness_data, (std_info, srt_label)) } | HeapRep _ ptrs nonptrs closure_type <- smrep - = do { let layout = packIntsCLit dflags ptrs nonptrs + = do { let layout = packIntsCLit platform ptrs nonptrs ; (prof_lits, prof_data) <- mkProfLits platform prof ; let (srt_label, srt_bitmap) = mkSRTLit dflags info_lbl srt ; (mb_srt_field, mb_layout, extra_bits, ct_data) @@ -238,14 +238,14 @@ mkInfoTableContents dflags -- Layout known (one free var); we use the layout field for offset mk_pieces (Fun arity (ArgSpec fun_type)) srt_label - = do { let extra_bits = packIntsCLit dflags fun_type arity : srt_label + = do { let extra_bits = packIntsCLit platform fun_type arity : srt_label ; return (Nothing, Nothing, extra_bits, []) } mk_pieces (Fun arity (ArgGen arg_bits)) srt_label = do { (liveness_lit, liveness_data) <- mkLivenessBits dflags arg_bits ; let fun_type | null liveness_data = aRG_GEN | otherwise = aRG_GEN_BIG - extra_bits = [ packIntsCLit dflags fun_type arity ] + extra_bits = [ packIntsCLit platform fun_type arity ] ++ (if inlineSRT dflags then [] else [ srt_lit ]) ++ [ liveness_lit, slow_entry ] ; return (Nothing, Nothing, extra_bits, liveness_data) } @@ -259,11 +259,10 @@ mkInfoTableContents dflags mkInfoTableContents _ _ _ = panic "mkInfoTableContents" -- NonInfoTable dealt with earlier -packIntsCLit :: DynFlags -> Int -> Int -> CmmLit -packIntsCLit dflags a b = packHalfWordsCLit dflags +packIntsCLit :: Platform -> Int -> Int -> CmmLit +packIntsCLit platform a b = packHalfWordsCLit platform (toStgHalfWord platform (fromIntegral a)) (toStgHalfWord platform (fromIntegral b)) - where platform = targetPlatform dflags mkSRTLit :: DynFlags ===================================== compiler/GHC/Cmm/Utils.hs ===================================== @@ -225,19 +225,18 @@ mkRODataLits lbl lits mkStgWordCLit :: Platform -> StgWord -> CmmLit mkStgWordCLit platform wd = CmmInt (fromStgWord wd) (wordWidth platform) -packHalfWordsCLit :: DynFlags -> StgHalfWord -> StgHalfWord -> CmmLit +packHalfWordsCLit :: Platform -> StgHalfWord -> StgHalfWord -> CmmLit -- Make a single word literal in which the lower_half_word is -- at the lower address, and the upper_half_word is at the -- higher address -- ToDo: consider using half-word lits instead -- but be careful: that's vulnerable when reversed -packHalfWordsCLit dflags lower_half_word upper_half_word - = if wORDS_BIGENDIAN dflags - then mkWordCLit platform ((l `shiftL` halfWordSizeInBits platform) .|. u) - else mkWordCLit platform (l .|. (u `shiftL` halfWordSizeInBits platform)) +packHalfWordsCLit platform lower_half_word upper_half_word + = case platformByteOrder platform of + BigEndian -> mkWordCLit platform ((l `shiftL` halfWordSizeInBits platform) .|. u) + LittleEndian -> mkWordCLit platform (l .|. (u `shiftL` halfWordSizeInBits platform)) where l = fromStgHalfWord lower_half_word u = fromStgHalfWord upper_half_word - platform = targetPlatform dflags --------------------------------------------------- -- ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -520,41 +520,41 @@ pprStatics dflags = pprStatics' (CmmStaticLit (CmmFloat f W32) : rest) -- odd numbers of floats are padded to a word by mkVirtHeapOffsetsWithPadding | wordWidth platform == W64, CmmStaticLit (CmmInt 0 W32) : rest' <- rest - -> pprLit1 dflags (floatToWord dflags f) : pprStatics' rest' + -> pprLit1 dflags (floatToWord platform f) : pprStatics' rest' -- adjacent floats aren't padded but combined into a single word | wordWidth platform == W64, CmmStaticLit (CmmFloat g W32) : rest' <- rest - -> pprLit1 dflags (floatPairToWord dflags f g) : pprStatics' rest' + -> pprLit1 dflags (floatPairToWord platform f g) : pprStatics' rest' | wordWidth platform == W32 - -> pprLit1 dflags (floatToWord dflags f) : pprStatics' rest + -> pprLit1 dflags (floatToWord platform f) : pprStatics' rest | otherwise -> pprPanic "pprStatics: float" (vcat (map ppr' rest)) where ppr' (CmmStaticLit l) = ppr (cmmLitType platform l) ppr' _other = text "bad static!" (CmmStaticLit (CmmFloat f W64) : rest) - -> map (pprLit1 dflags) (doubleToWords dflags f) ++ pprStatics' rest + -> map (pprLit1 dflags) (doubleToWords platform f) ++ pprStatics' rest (CmmStaticLit (CmmInt i W64) : rest) | wordWidth platform == W32 - -> if wORDS_BIGENDIAN dflags - then pprStatics' (CmmStaticLit (CmmInt q W32) : - CmmStaticLit (CmmInt r W32) : rest) - else pprStatics' (CmmStaticLit (CmmInt r W32) : - CmmStaticLit (CmmInt q W32) : rest) + -> case platformByteOrder platform of + BigEndian -> pprStatics' (CmmStaticLit (CmmInt q W32) : + CmmStaticLit (CmmInt r W32) : rest) + LittleEndian -> pprStatics' (CmmStaticLit (CmmInt r W32) : + CmmStaticLit (CmmInt q W32) : rest) where r = i .&. 0xffffffff q = i `shiftR` 32 (CmmStaticLit (CmmInt a W32) : CmmStaticLit (CmmInt b W32) : rest) | wordWidth platform == W64 - -> if wORDS_BIGENDIAN dflags - then pprStatics' (CmmStaticLit (CmmInt ((shiftL a 32) .|. b) W64) : rest) - else pprStatics' (CmmStaticLit (CmmInt ((shiftL b 32) .|. a) W64) : rest) + -> case platformByteOrder platform of + BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 32) .|. b) W64) : rest) + LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 32) .|. a) W64) : rest) (CmmStaticLit (CmmInt a W16) : CmmStaticLit (CmmInt b W16) : rest) | wordWidth platform == W32 - -> if wORDS_BIGENDIAN dflags - then pprStatics' (CmmStaticLit (CmmInt ((shiftL a 16) .|. b) W32) : rest) - else pprStatics' (CmmStaticLit (CmmInt ((shiftL b 16) .|. a) W32) : rest) + -> case platformByteOrder platform of + BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 16) .|. b) W32) : rest) + LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 16) .|. a) W32) : rest) (CmmStaticLit (CmmInt _ w) : _) | w /= wordWidth platform @@ -1271,8 +1271,8 @@ castFloatToWord32Array = U.castSTUArray castDoubleToWord64Array :: STUArray s Int Double -> ST s (STUArray s Int Word64) castDoubleToWord64Array = U.castSTUArray -floatToWord :: DynFlags -> Rational -> CmmLit -floatToWord dflags r +floatToWord :: Platform -> Rational -> CmmLit +floatToWord platform r = runST (do arr <- newArray_ ((0::Int),0) writeArray arr 0 (fromRational r) @@ -1281,12 +1281,13 @@ floatToWord dflags r return (CmmInt (toInteger w32 `shiftL` wo) (wordWidth platform)) ) where wo | wordWidth platform == W64 - , wORDS_BIGENDIAN dflags = 32 - | otherwise = 0 - platform = targetPlatform dflags + , BigEndian <- platformByteOrder platform + = 32 + | otherwise + = 0 -floatPairToWord :: DynFlags -> Rational -> Rational -> CmmLit -floatPairToWord dflags r1 r2 +floatPairToWord :: Platform -> Rational -> Rational -> CmmLit +floatPairToWord platform r1 r2 = runST (do arr <- newArray_ ((0::Int),1) writeArray arr 0 (fromRational r1) @@ -1297,15 +1298,15 @@ floatPairToWord dflags r1 r2 return (pprWord32Pair w32_1 w32_2) ) where pprWord32Pair w32_1 w32_2 - | wORDS_BIGENDIAN dflags = + | BigEndian <- platformByteOrder platform = CmmInt ((shiftL i1 32) .|. i2) W64 | otherwise = CmmInt ((shiftL i2 32) .|. i1) W64 where i1 = toInteger w32_1 i2 = toInteger w32_2 -doubleToWords :: DynFlags -> Rational -> [CmmLit] -doubleToWords dflags r +doubleToWords :: Platform -> Rational -> [CmmLit] +doubleToWords platform r = runST (do arr <- newArray_ ((0::Int),1) writeArray arr 0 (fromRational r) @@ -1314,8 +1315,6 @@ doubleToWords dflags r return (pprWord64 w64) ) where targetWidth = wordWidth platform - platform = targetPlatform dflags - targetBE = wORDS_BIGENDIAN dflags pprWord64 w64 | targetWidth == W64 = [ CmmInt (toInteger w64) targetWidth ] @@ -1324,9 +1323,9 @@ doubleToWords dflags r , CmmInt (toInteger targetW2) targetWidth ] | otherwise = panic "doubleToWords.pprWord64" - where (targetW1, targetW2) - | targetBE = (wHi, wLo) - | otherwise = (wLo, wHi) + where (targetW1, targetW2) = case platformByteOrder platform of + BigEndian -> (wHi, wLo) + LittleEndian -> (wLo, wHi) wHi = w64 `shiftR` 32 wLo = w64 .&. 0xFFFFffff ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -245,7 +245,7 @@ ppr_co_ax_branch ppr_rhs fam_tc branch -- Eta-expand LHS and RHS types, because sometimes data family -- instances are eta-reduced. - -- See Note [Eta reduction for data families] in GHC.Core.FamInstEnv. + -- See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. (ee_tvs, ee_lhs, ee_rhs) = etaExpandCoAxBranch branch pp_lhs = pprIfaceTypeApp topPrec (toIfaceTyCon fam_tc) ===================================== compiler/GHC/Core/Coercion/Axiom.hs ===================================== @@ -235,7 +235,7 @@ data CoAxBranch , cab_tvs :: [TyVar] -- Bound type variables; not necessarily fresh , cab_eta_tvs :: [TyVar] -- Eta-reduced tyvars -- See Note [CoAxBranch type variables] - -- cab_tvs and cab_lhs may be eta-reduded; see + -- cab_tvs and cab_lhs may be eta-reduced; see -- Note [Eta reduction for data families] , cab_cvs :: [CoVar] -- Bound coercion variables -- Always empty, for now. @@ -443,9 +443,13 @@ looked like (See #9692, #14179, and #15845 for examples of what can go wrong if we don't eta-expand when showing things to the user.) -(See also Note [Newtype eta] in GHC.Core.TyCon. This is notionally separate -and deals with the axiom connecting a newtype with its representation -type; but it too is eta-reduced.) +See also: + +* Note [Newtype eta] in GHC.Core.TyCon. This is notionally separate + and deals with the axiom connecting a newtype with its representation + type; but it too is eta-reduced. +* Note [Implementing eta reduction for data families] in TcInstDcls. This + describes the implementation details of this eta reduction happen. -} instance Eq (CoAxiom br) where ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -118,6 +118,7 @@ data FamInst -- See Note [FamInsts and CoAxioms] , fi_tys :: [Type] -- The LHS type patterns -- May be eta-reduced; see Note [Eta reduction for data families] + -- in GHC.Core.Coercion.Axiom , fi_rhs :: Type -- the RHS, with its freshened vars } @@ -132,7 +133,8 @@ Note [Arity of data families] Data family instances might legitimately be over- or under-saturated. Under-saturation has two potential causes: - U1) Eta reduction. See Note [Eta reduction for data families]. + U1) Eta reduction. See Note [Eta reduction for data families] in + GHC.Core.Coercion.Axiom. U2) When the user has specified a return kind instead of written out patterns. Example: @@ -160,8 +162,8 @@ Over-saturation is also possible: However, we require that any over-saturation is eta-reducible. That is, we require that any extra patterns be bare unrepeated type variables; - see Note [Eta reduction for data families]. Accordingly, the FamInst - is never over-saturated. + see Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. + Accordingly, the FamInst is never over-saturated. Why can we allow such flexibility for data families but not for type families? Because data families can be decomposed -- that is, they are generative and @@ -335,7 +337,7 @@ Then we get a data type for each instance, and an axiom: axiom ax8 a :: T Bool [a] ~ TBoolList a These two axioms for T, one with one pattern, one with two; -see Note [Eta reduction for data families] +see Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom Note [FamInstEnv determinism] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -479,7 +481,7 @@ irrelevant (clause 1 of compatible) or benign (clause 2 of compatible). Note [Compatibility of eta-reduced axioms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In newtype instances of data families we eta-reduce the axioms, -See Note [Eta reduction for data families] in GHC.Core.FamInstEnv. This means that +See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. This means that we sometimes need to test compatibility of two axioms that were eta-reduced to different degrees, e.g.: @@ -1057,7 +1059,7 @@ We handle data families and type families separately here: * For data family instances, though, we need to re-split for each instance, because the breakdown might be different for each instance. Why? Because of eta reduction; see - Note [Eta reduction for data families]. + Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom. -} -- checks if one LHS is dominated by a list of other branches ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -240,7 +240,7 @@ See also Note [Wrappers for data instance tycons] in GHC.Types.Id.Make DataFamInstTyCon T [Int] ax_ti * The axiom ax_ti may be eta-reduced; see - Note [Eta reduction for data families] in GHC.Core.FamInstEnv + Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom * Data family instances may have a different arity than the data family. See Note [Arity of data families] in GHC.Core.FamInstEnv @@ -1100,8 +1100,9 @@ data AlgTyConFlav -- and R:T is the representation TyCon (ie this one) -- and a,b,c are the tyConTyVars of this TyCon -- - -- BUT may be eta-reduced; see FamInstEnv - -- Note [Eta reduction for data families] + -- BUT may be eta-reduced; see + -- Note [Eta reduction for data families] in + -- GHC.Core.Coercion.Axiom -- Cached fields of the CoAxiom, but adjusted to -- use the tyConTyVars of this TyCon ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -1319,10 +1319,11 @@ checkAllNonVoid :: RecTcChecker -> Delta -> [Type] -> DsM Bool checkAllNonVoid rec_ts amb_cs strict_arg_tys = do let definitely_inhabited = definitelyInhabitedType (delta_ty_st amb_cs) tys_to_check <- filterOutM definitely_inhabited strict_arg_tys + -- See Note [Fuel for the inhabitation test] let rec_max_bound | tys_to_check `lengthExceeds` 1 = 1 | otherwise - = defaultRecTcMaxBound + = 3 rec_ts' = setRecTcMaxBound rec_max_bound rec_ts allM (nonVoid rec_ts' amb_cs) tys_to_check @@ -1342,6 +1343,7 @@ nonVoid rec_ts amb_cs strict_arg_ty = do mb_cands <- inhabitationCandidates amb_cs strict_arg_ty case mb_cands of Right (tc, _, cands) + -- See Note [Fuel for the inhabitation test] | Just rec_ts' <- checkRecTc rec_ts tc -> anyM (cand_is_inhabitable rec_ts' amb_cs) cands -- A strict argument type is inhabitable by a terminating value if @@ -1390,7 +1392,7 @@ definitelyInhabitedType ty_st ty = do null (dataConImplBangs con) -- (2) {- Note [Strict argument type constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the ConVar case of clause processing, each conlike K traditionally generates two different forms of constraints: @@ -1420,6 +1422,7 @@ say, `K2 undefined` or `K2 (let x = x in x)`.) Since neither the term nor type constraints mentioned above take strict argument types into account, we make use of the `nonVoid` function to determine whether a strict type is inhabitable by a terminating value or not. +We call this the "inhabitation test". `nonVoid ty` returns True when either: 1. `ty` has at least one InhabitationCandidate for which both its term and type @@ -1445,15 +1448,20 @@ determine whether a strict type is inhabitable by a terminating value or not. `nonVoid MyVoid` returns False. The InhabitationCandidate for the MkMyVoid constructor contains Void as a strict argument type, and since `nonVoid Void` returns False, that InhabitationCandidate is discarded, leaving no others. +* Whether or not a type is inhabited is undecidable in general. + See Note [Fuel for the inhabitation test]. +* For some types, inhabitation is evident immediately and we don't need to + perform expensive tests. See Note [Types that are definitely inhabitable]. -* Performance considerations +Note [Fuel for the inhabitation test] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Whether or not a type is inhabited is undecidable in general. As a result, we +can run into infinite loops in `nonVoid`. Therefore, we adopt a fuel-based +approach to prevent that. -We must be careful when recursively calling `nonVoid` on the strict argument -types of an InhabitationCandidate, because doing so naïvely can cause GHC to -fall into an infinite loop. Consider the following example: +Consider the following example: data Abyss = MkAbyss !Abyss - stareIntoTheAbyss :: Abyss -> a stareIntoTheAbyss x = case x of {} @@ -1474,7 +1482,6 @@ stareIntoTheAbyss above. Then again, the same problem occurs with recursive newtypes, like in the following code: newtype Chasm = MkChasm Chasm - gazeIntoTheChasm :: Chasm -> a gazeIntoTheChasm x = case x of {} -- Erroneously warned as non-exhaustive @@ -1498,9 +1505,26 @@ maximum recursion depth to 1 to mitigate the problem. If the branching factor is exactly 1 (i.e., we have a linear chain instead of a tree), then it's okay to stick with a larger maximum recursion depth. +In #17977 we saw that the defaultRecTcMaxBound (100 at the time of writing) was +too large and had detrimental effect on performance of the coverage checker. +Given that we only commit to a best effort anyway, we decided to substantially +decrement the recursion depth to 3, at the cost of precision in some edge cases +like + + data Nat = Z | S Nat + data Down :: Nat -> Type where + Down :: !(Down n) -> Down (S n) + f :: Down (S (S (S (S (S Z))))) -> () + f x = case x of {} + +Since the coverage won't bother to instantiate Down 4 levels deep to see that it +is in fact uninhabited, it will emit a inexhaustivity warning for the case. + +Note [Types that are definitely inhabitable] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another microoptimization applies to data types like this one: - data S a = ![a] !T + data S a = S ![a] !T Even though there is a strict field of type [a], it's quite silly to call nonVoid on it, since it's "obvious" that it is inhabitable. To make this ===================================== compiler/GHC/Llvm/Types.hs ===================================== @@ -225,26 +225,26 @@ ppPlainName (LMLitVar x ) = ppLit x -- | Print a literal value. No type. ppLit :: LlvmLit -> SDoc -ppLit (LMIntLit i (LMInt 32)) = ppr (fromInteger i :: Int32) -ppLit (LMIntLit i (LMInt 64)) = ppr (fromInteger i :: Int64) -ppLit (LMIntLit i _ ) = ppr ((fromInteger i)::Int) -ppLit (LMFloatLit r LMFloat ) = ppFloat $ narrowFp r -ppLit (LMFloatLit r LMDouble) = ppDouble r -ppLit f@(LMFloatLit _ _) = pprPanic "ppLit" (text "Can't print this float literal: " <> ppr f) -ppLit (LMVectorLit ls ) = char '<' <+> ppCommaJoin ls <+> char '>' -ppLit (LMNullLit _ ) = text "null" --- #11487 was an issue where we passed undef for some arguments --- that were actually live. By chance the registers holding those --- arguments usually happened to have the right values anyways, but --- that was not guaranteed. To find such bugs reliably, we set the --- flag below when validating, which replaces undef literals (at --- common types) with values that are likely to cause a crash or test --- failure. -ppLit (LMUndefLit t ) = sdocWithDynFlags f - where f dflags - | gopt Opt_LlvmFillUndefWithGarbage dflags, - Just lit <- garbageLit t = ppLit lit - | otherwise = text "undef" +ppLit l = sdocWithDynFlags $ \dflags -> case l of + (LMIntLit i (LMInt 32)) -> ppr (fromInteger i :: Int32) + (LMIntLit i (LMInt 64)) -> ppr (fromInteger i :: Int64) + (LMIntLit i _ ) -> ppr ((fromInteger i)::Int) + (LMFloatLit r LMFloat ) -> ppFloat (targetPlatform dflags) $ narrowFp r + (LMFloatLit r LMDouble) -> ppDouble (targetPlatform dflags) r + f@(LMFloatLit _ _) -> pprPanic "ppLit" (text "Can't print this float literal: " <> ppr f) + (LMVectorLit ls ) -> char '<' <+> ppCommaJoin ls <+> char '>' + (LMNullLit _ ) -> text "null" + -- #11487 was an issue where we passed undef for some arguments + -- that were actually live. By chance the registers holding those + -- arguments usually happened to have the right values anyways, but + -- that was not guaranteed. To find such bugs reliably, we set the + -- flag below when validating, which replaces undef literals (at + -- common types) with values that are likely to cause a crash or test + -- failure. + (LMUndefLit t ) + | gopt Opt_LlvmFillUndefWithGarbage dflags + , Just lit <- garbageLit t -> ppLit lit + | otherwise -> text "undef" garbageLit :: LlvmType -> Maybe LlvmLit garbageLit t@(LMInt w) = Just (LMIntLit (0xbbbbbbbbbbbbbbb0 `mod` (2^w)) t) @@ -836,19 +836,20 @@ instance Outputable LlvmCastOp where -- regardless of underlying architecture. -- -- See Note [LLVM Float Types]. -ppDouble :: Double -> SDoc -ppDouble d +ppDouble :: Platform -> Double -> SDoc +ppDouble platform d = let bs = doubleToBytes d hex d' = case showHex d' "" of - [] -> error "dToStr: too few hex digits for float" - [x] -> ['0',x] - [x,y] -> [x,y] - _ -> error "dToStr: too many hex digits for float" + [] -> error "ppDouble: too few hex digits for float" + [x] -> ['0',x] + [x,y] -> [x,y] + _ -> error "ppDouble: too many hex digits for float" - in sdocWithDynFlags (\dflags -> - let fixEndian = if wORDS_BIGENDIAN dflags then id else reverse - str = map toUpper $ concat $ fixEndian $ map hex bs - in text "0x" <> text str) + fixEndian = case platformByteOrder platform of + BigEndian -> id + LittleEndian -> reverse + str = map toUpper $ concat $ fixEndian $ map hex bs + in text "0x" <> text str -- Note [LLVM Float Types] -- ~~~~~~~~~~~~~~~~~~~~~~~ @@ -875,8 +876,8 @@ widenFp :: Float -> Double {-# NOINLINE widenFp #-} widenFp = float2Double -ppFloat :: Float -> SDoc -ppFloat = ppDouble . widenFp +ppFloat :: Platform -> Float -> SDoc +ppFloat platform = ppDouble platform . widenFp -------------------------------------------------------------------------------- ===================================== compiler/GHC/Runtime/Heap/Inspect.hs ===================================== @@ -865,10 +865,9 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 -- This is a bit involved since we allow packing multiple fields -- within a single word. See also -- GHC.StgToCmm.Layout.mkVirtHeapOffsetsWithPadding - dflags <- getDynFlags - let platform = targetPlatform dflags - word_size = platformWordSizeInBytes platform - big_endian = wORDS_BIGENDIAN dflags + platform <- targetPlatform <$> getDynFlags + let word_size = platformWordSizeInBytes platform + endian = platformByteOrder platform size_b = primRepSizeB platform rep -- Align the start offset (eg, 2-byte value should be 2-byte -- aligned). But not more than to a word. The offset calculation @@ -877,7 +876,7 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 !aligned_idx = roundUpTo arr_i (min word_size size_b) !new_arr_i = aligned_idx + size_b ws | size_b < word_size = - [index size_b aligned_idx word_size big_endian] + [index size_b aligned_idx word_size endian] | otherwise = let (q, r) = size_b `quotRem` word_size in ASSERT( r == 0 ) @@ -892,7 +891,7 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 (error "unboxedTupleTerm: no HValue for unboxed tuple") terms -- Extract a sub-word sized field from a word - index item_size_b index_b word_size big_endian = + index item_size_b index_b word_size endian = (word .&. (mask `shiftL` moveBytes)) `shiftR` moveBytes where mask :: Word @@ -903,9 +902,9 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 _ -> panic ("Weird byte-index: " ++ show index_b) (q,r) = index_b `quotRem` word_size word = array!!q - moveBytes = if big_endian - then word_size - (r + item_size_b) * 8 - else r * 8 + moveBytes = case endian of + BigEndian -> word_size - (r + item_size_b) * 8 + LittleEndian -> r * 8 -- | Fast, breadth-first Type reconstruction ===================================== compiler/typecheck/TcDeriv.hs ===================================== @@ -1312,7 +1312,7 @@ write it out return x = MkT [x] ... etc ... -See Note [Eta reduction for data families] in GHC.Core.FamInstEnv +See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom %************************************************************************ %* * ===================================== compiler/typecheck/TcInstDcls.hs ===================================== @@ -667,7 +667,7 @@ tcDataFamInstDecl mb_clsinfo new_or_data -- Eta-reduce the axiom if possible - -- Quite tricky: see Note [Eta-reduction for data families] + -- Quite tricky: see Note [Implementing eta reduction for data families] ; let (eta_pats, eta_tcbs) = eta_reduce fam_tc pats eta_tvs = map binderVar eta_tcbs post_eta_qtvs = filterOut (`elem` eta_tvs) qtvs @@ -761,7 +761,7 @@ tcDataFamInstDecl mb_clsinfo ; return (fam_inst, m_deriv_info) } where eta_reduce :: TyCon -> [Type] -> ([Type], [TyConBinder]) - -- See Note [Eta reduction for data families] in GHC.Core.FamInstEnv + -- See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom -- Splits the incoming patterns into two: the [TyVar] -- are the patterns that can be eta-reduced away. -- e.g. T [a] Int a d c ==> (T [a] Int a, [d,c]) @@ -887,8 +887,8 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. Inst.deeplySkolemise and TcUnify.tcSkolemise Examples in indexed-types/should_compile/T12369 -Note [Eta-reduction for data families] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Implementing eta reduction for data families] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data D :: * -> * -> * -> * -> * @@ -906,7 +906,10 @@ and an axiom to connect them except that we'll eta-reduce the axiom to axiom AxDrep forall a b. D [(a,b]] = Drep a b -There are several fiddly subtleties lurking here + +This is described at some length in Note [Eta reduction for data families] +in GHC.Core.Coercion.Axiom. There are several fiddly subtleties lurking here, +however, so this Note aims to describe these subtleties: * The representation tycon Drep is parameterised over the free variables of the pattern, in no particular order. So there is no ===================================== compiler/typecheck/TcSplice.hs ===================================== @@ -2046,7 +2046,7 @@ reifyFamilyInstance is_poly_tvs (FamInst { fi_flavor = flavor DataFamilyInst rep_tc -> do { let -- eta-expand lhs types, because sometimes data/newtype -- instances are eta-reduced; See #9692 - -- See Note [Eta reduction for data families] in GHC.Core.FamInstEnv + -- See Note [Eta reduction for data families] in GHC.Core.Coercion.Axiom (ee_tvs, ee_lhs, _) = etaExpandCoAxBranch branch fam' = reifyName fam dataCons = tyConDataCons rep_tc ===================================== configure.ac ===================================== @@ -952,6 +952,10 @@ else AC_SUBST([Cabal64bit],[False]) fi AC_SUBST(TargetWordSize) + +AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) +AC_SUBST(TargetWordBigEndian) + FP_CHECK_FUNC([WinExec], [@%:@include ], [WinExec("",0)]) ===================================== distrib/configure.ac.in ===================================== @@ -177,6 +177,17 @@ fi TargetWordSize=$ac_cv_sizeof_void_p AC_SUBST(TargetWordSize) +dnl TargetWordBigEndian for settings file +AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) +dnl Check that the toolchain we have is consistent with what the compiler expects +if test "x$TargetWordBigEndian" != "x at TargetWordBigEndian@"; then + AC_MSG_ERROR([This binary distribution produces binaries for a target with + a different byte order than your target toolchain. + Are you sure your toolchain targets the intended target platform + of this compiler?]) +fi +AC_SUBST(TargetWordBigEndian) + # dnl ** how to invoke `ar' and `ranlib' # ===================================== hadrian/cfg/system.config.in ===================================== @@ -146,6 +146,7 @@ settings-llc-command = @SettingsLlcCommand@ settings-opt-command = @SettingsOptCommand@ target-word-size = @TargetWordSize@ +target-word-big-endian = @TargetWordBigEndian@ target-has-gnu-nonexec-stack = @TargetHasGnuNonexecStack@ target-has-ident-directive = @TargetHasIdentDirective@ target-has-subsections-via-symbols = @TargetHasSubsectionsViaSymbols@ ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -301,6 +301,7 @@ generateSettings = do , ("target os", getSetting TargetOsHaskell) , ("target arch", getSetting TargetArchHaskell) , ("target word size", expr $ lookupValueOrError configFile "target-word-size") + , ("target word big endian", expr $ lookupValueOrError configFile "target-word-big-endian") , ("target has GNU nonexec stack", expr $ lookupValueOrError configFile "target-has-gnu-nonexec-stack") , ("target has .ident directive", expr $ lookupValueOrError configFile "target-has-ident-directive") , ("target has subsections via symbols", expr $ lookupValueOrError configFile "target-has-subsections-via-symbols") ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -29,9 +29,12 @@ toolArgs = do compileAndLinkHs :: Args compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do ways <- getLibraryWays + useColor <- shakeColor <$> expr getShakeOptions let hasVanilla = elem vanilla ways hasDynamic = elem dynamic ways mconcat [ arg "-Wall" + , not useColor ? builder (Ghc CompileHs) ? + arg "-fdiagnostics-color=never" , (hasVanilla && hasDynamic) ? builder (Ghc CompileHs) ? platformSupportsSharedLibs ? way vanilla ? arg "-dynamic-too" ===================================== includes/ghc.mk ===================================== @@ -236,6 +236,7 @@ $(includes_SETTINGS) : includes/Makefile | $$(dir $$@)/. @echo ',("target os", "$(HaskellTargetOs)")' >> $@ @echo ',("target arch", "$(HaskellTargetArch)")' >> $@ @echo ',("target word size", "$(TargetWordSize)")' >> $@ + @echo ',("target word big endian", "$(TargetWordBigEndian)")' >> $@ @echo ',("target has GNU nonexec stack", "$(TargetHasGnuNonexecStack)")' >> $@ @echo ',("target has .ident directive", "$(TargetHasIdentDirective)")' >> $@ @echo ',("target has subsections via symbols", "$(TargetHasSubsectionsViaSymbols)")' >> $@ ===================================== libraries/base/GHC/IO/Handle/Text.hs ===================================== @@ -466,7 +466,7 @@ getSomeCharacters handle_ at Handle__{..} buf at Buffer{..} = -- | The 'hGetContents'' operation reads all input on the given handle -- before returning it as a 'String' and closing the handle. -- --- @since 4.14.0.0 +-- @since 4.15.0.0 hGetContents' :: Handle -> IO String hGetContents' handle = do ===================================== libraries/base/System/IO.hs ===================================== @@ -312,7 +312,7 @@ getContents = hGetContents stdin -- which is fully read before being returned -- (same as 'hGetContents'' 'stdin'). -- --- @since 4.14.0.0 +-- @since 4.15.0.0 getContents' :: IO String getContents' = hGetContents' stdin @@ -337,7 +337,7 @@ readFile name = openFile name ReadMode >>= hGetContents -- returns the contents of the file as a string. -- The file is fully read before being returned, as with 'getContents''. -- --- @since 4.14.0.0 +-- @since 4.15.0.0 readFile' :: FilePath -> IO String readFile' name = openFile name ReadMode >>= hGetContents' ===================================== libraries/base/changelog.md ===================================== @@ -6,6 +6,9 @@ call, ensuring that the call can be interrupted with `SIGINT` on POSIX systems. + * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: + Strict IO variants of `hGetContents`, `getContents`, and `readFile`. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 @@ -51,9 +54,6 @@ * Add `IsList` instance for `ZipList`. - * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: - Strict IO variants of `hGetContents`, `getContents`, and `readFile`. - ## 4.13.0.0 *July 2019* * Bundled with GHC 8.8.1 ===================================== libraries/ghc-boot/GHC/Platform.hs ===================================== @@ -12,6 +12,7 @@ module GHC.Platform ( ArmISAExt(..), ArmABI(..), PPC_64ABI(..), + ByteOrder(..), target32Bit, isARM, @@ -38,6 +39,7 @@ where import Prelude -- See Note [Why do we import Prelude here?] import GHC.Read +import GHC.ByteOrder (ByteOrder(..)) import Data.Word import Data.Int @@ -53,19 +55,17 @@ data PlatformMini -- | Contains enough information for the native code generator to emit -- code for this platform. -data Platform - = Platform { - platformMini :: PlatformMini, - -- Word size in bytes (i.e. normally 4 or 8, - -- for 32bit and 64bit platforms respectively) - platformWordSize :: PlatformWordSize, - platformUnregisterised :: Bool, - platformHasGnuNonexecStack :: Bool, - platformHasIdentDirective :: Bool, - platformHasSubsectionsViaSymbols :: Bool, - platformIsCrossCompiling :: Bool - } - deriving (Read, Show, Eq) +data Platform = Platform + { platformMini :: PlatformMini + , platformWordSize :: PlatformWordSize + , platformByteOrder :: ByteOrder + , platformUnregisterised :: Bool + , platformHasGnuNonexecStack :: Bool + , platformHasIdentDirective :: Bool + , platformHasSubsectionsViaSymbols :: Bool + , platformIsCrossCompiling :: Bool + } + deriving (Read, Show, Eq) data PlatformWordSize = PW4 -- ^ A 32-bit platform ===================================== libraries/ghc-boot/GHC/Settings.hs ===================================== @@ -36,6 +36,7 @@ getTargetPlatform settingsFile mySettings = do targetArch <- readSetting "target arch" targetOS <- readSetting "target os" targetWordSize <- readSetting "target word size" + targetWordBigEndian <- getBooleanSetting "target word big endian" targetUnregisterised <- getBooleanSetting "Unregisterised" targetHasGnuNonexecStack <- getBooleanSetting "target has GNU nonexec stack" targetHasIdentDirective <- getBooleanSetting "target has .ident directive" @@ -48,6 +49,7 @@ getTargetPlatform settingsFile mySettings = do , platformMini_os = targetOS } , platformWordSize = targetWordSize + , platformByteOrder = if targetWordBigEndian then BigEndian else LittleEndian , platformUnregisterised = targetUnregisterised , platformHasGnuNonexecStack = targetHasGnuNonexecStack , platformHasIdentDirective = targetHasIdentDirective ===================================== mk/config.mk.in ===================================== @@ -494,6 +494,7 @@ HaskellHostArch = @HaskellHostArch@ HaskellTargetOs = @HaskellTargetOs@ HaskellTargetArch = @HaskellTargetArch@ TargetWordSize = @TargetWordSize@ +TargetWordBigEndian = @TargetWordBigEndian@ TargetHasGnuNonexecStack = @TargetHasGnuNonexecStack@ TargetHasIdentDirective = @TargetHasIdentDirective@ TargetHasSubsectionsViaSymbols = @TargetHasSubsectionsViaSymbols@ ===================================== testsuite/tests/pmcheck/should_compile/T17977.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +module Bug where + +import Data.Kind +import Data.Type.Equality + +data Nat = Z | S Nat + +data SNat :: Nat -> Type where + SZ :: SNat Z + SS :: SNat n -> SNat (S n) + +type family S' (n :: Nat) :: Nat where + S' n = S n + +data R :: Nat -> Nat -> Nat -> Type where + MkR :: !(R m n o) -> R (S m) n (S o) + +type family NatPlus (m :: Nat) (n :: Nat) :: Nat where + NatPlus Z n = n + NatPlus (S m) n = S' (NatPlus m n) + +f :: forall (m :: Nat) (n :: Nat) (o :: Nat). + SNat m -> SNat n -> SNat o + -> R m n o -> NatPlus m n :~: o +f (SS sm) sn (SS so) (MkR r) + | Refl <- f sm sn so r + = Refl ===================================== testsuite/tests/pmcheck/should_compile/T17977b.hs ===================================== @@ -0,0 +1,24 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE EmptyCase #-} +module Bug where + +import Data.Kind + +data Nat = Z | S Nat + +data Down :: Nat -> Type where + Down :: !(Down n) -> Down (S n) + +data Up :: Nat -> Type where + Up :: !(Up (S n)) -> Up n + +f :: Down n -> () +f (Down r) = () + +f' :: Down (S (S (S (S Z)))) -> () +f' (Down r) = () + +g :: Up n -> () +g (Up r) = () ===================================== testsuite/tests/pmcheck/should_compile/T17977b.stderr ===================================== @@ -0,0 +1,4 @@ + +T17977b.hs:21:1: warning: [-Woverlapping-patterns (in -Wdefault)] + Pattern match has inaccessible right hand side + In an equation for ‘f'’: f' (Down r) = ... ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -114,6 +114,10 @@ test('T17703', normal, compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17783', normal, compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T17977', collect_compiler_stats('bytes allocated',10), compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T17977b', collect_compiler_stats('bytes allocated',10), compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, ===================================== utils/deriveConstants/Main.hs ===================================== @@ -672,7 +672,6 @@ wanteds os = concat -- Amount of pointer bits used for semi-tagging constructor closures ,constantWord Haskell "TAG_BITS" "TAG_BITS" - ,constantBool Haskell "WORDS_BIGENDIAN" "defined(WORDS_BIGENDIAN)" ,constantBool Haskell "DYNAMIC_BY_DEFAULT" "defined(DYNAMIC_BY_DEFAULT)" ,constantWord Haskell "LDV_SHIFT" "LDV_SHIFT" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f54b3e379e712a2f6b1c8a2ccce0d6b7353486d5...ecdc6599d4aacbc8593ef4b415b8bac7dbc789c0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f54b3e379e712a2f6b1c8a2ccce0d6b7353486d5...ecdc6599d4aacbc8593ef4b415b8bac7dbc789c0 You're receiving 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 1 07:10:04 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 01 Apr 2020 03:10:04 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 11 commits: Expect T4267 to pass Message-ID: <5e843e4c45e5d_61676830044210585c@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 5f93466a by Ömer Sinan Ağacan at 2020-04-01T03:10:02-04:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Unique/Supply.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8822bbc170c2d6779d7c66d6f1aea1bc967babd7...5f93466a1814b728caa264ac341c7483869331a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8822bbc170c2d6779d7c66d6f1aea1bc967babd7...5f93466a1814b728caa264ac341c7483869331a7 You're receiving 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 1 07:20:45 2020 From: gitlab at gitlab.haskell.org (Alp Mestanogullari) Date: Wed, 01 Apr 2020 03:20:45 -0400 Subject: [Git][ghc/ghc][wip/T16296] 11 commits: Expect T4267 to pass Message-ID: <5e8440cd1f9c8_61673f8198ee100c210897e@gitlab.haskell.org.mail> Alp Mestanogullari pushed to branch wip/T16296 at Glasgow Haskell Compiler / GHC Commits: f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 812c4750 by Simon Peyton Jones at 2020-04-01T03:20:38-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/095afdd91e7ceedb345764831b6db9cc36d0038c...812c475056e4e16b93ba1fa79d8b44b1329759b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/095afdd91e7ceedb345764831b6db9cc36d0038c...812c475056e4e16b93ba1fa79d8b44b1329759b1 You're receiving 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 1 08:03:39 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 04:03:39 -0400 Subject: [Git][ghc/ghc][wip/T16806] 4 commits: Clean up "Eta reduction for data families" Notes Message-ID: <5e844adb2937e_6167683004421209bf@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 35c6cd72 by Simon Jakobi at 2020-04-01T10:01:11+02:00 Use the new Data.IntMap.disjoint function Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 30 changed files: - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Module.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Set.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/ghc.cabal.in - compiler/iface/BuildTyCl.hs - compiler/typecheck/TcDeriv.hs - compiler/typecheck/TcHoleErrors.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcSimplify.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a880b6c6b85d2c23c2adef1068c23d475bc235e...35c6cd7297582131ea8fb0986039da0adbc18cb1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a880b6c6b85d2c23c2adef1068c23d475bc235e...35c6cd7297582131ea8fb0986039da0adbc18cb1 You're receiving 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 1 08:04:45 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 04:04:45 -0400 Subject: [Git][ghc/ghc][wip/T16806] Use Data.IntMap.disjoint Message-ID: <5e844b1def96a_6167e0e2c942121294@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: d2dd3c54 by Simon Jakobi at 2020-04-01T10:04:13+02:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 20 changed files: - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Module.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Set.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/ghc.cabal.in - compiler/iface/BuildTyCl.hs - compiler/typecheck/TcHoleErrors.hs - compiler/typecheck/TcSimplify.hs - hadrian/src/Rules/Documentation.hs Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -1173,7 +1173,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] is_flt_sc_arg var = isId var && not (isDeadBinder var) && isDictTy var_ty - && not (tyCoVarsOfType var_ty `intersectsVarSet` arg_set) + && tyCoVarsOfType var_ty `disjointVarSet` arg_set where var_ty = idType var @@ -2489,7 +2489,7 @@ filterCalls (CIS fn call_bag) dbs = extendVarSetList so_far (bindersOf db) | otherwise = so_far - ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) + ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set ---------------------- splitDictBinds :: Bag DictBind -> IdSet -> (Bag DictBind, Bag DictBind, IdSet) @@ -2519,7 +2519,7 @@ deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails deleteCallsMentioning bs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` bs) + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs deleteCallsFor :: [Id] -> CallDetails -> CallDetails -- Remove calls *for* bs ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -383,8 +383,8 @@ extendTCvSubstList subst tvs tys unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst -- Works when the ranges are disjoint unionTCvSubst (TCvSubst in_scope1 tenv1 cenv1) (TCvSubst in_scope2 tenv2 cenv2) - = ASSERT( not (tenv1 `intersectsVarEnv` tenv2) - && not (cenv1 `intersectsVarEnv` cenv2) ) + = ASSERT( tenv1 `disjointVarEnv` tenv2 + && cenv1 `disjointVarEnv` cenv2 ) TCvSubst (in_scope1 `unionInScope` in_scope2) (tenv1 `plusVarEnv` tenv2) (cenv1 `plusVarEnv` cenv2) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2112,7 +2112,7 @@ isValidJoinPointType arity ty where valid_under tvs arity ty | arity == 0 - = isEmptyVarSet (tvs `intersectVarSet` tyCoVarsOfType ty) + = tvs `disjointVarSet` tyCoVarsOfType ty | Just (t, ty') <- splitForAllTy_maybe ty = valid_under (tvs `extendVarSet` t) (arity-1) ty' | Just (_, res_ty) <- splitFunTy_maybe ty ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -1350,7 +1350,7 @@ glomSegments ctxt ((defs,uses,fwds,stmt) : segs) = (reverse yeses, reverse noes) where (noes, yeses) = span not_needed (reverse dus) - not_needed (defs,_,_,_) = not (intersectsNameSet defs uses) + not_needed (defs,_,_,_) = disjointNameSet defs uses ---------------------------------------------------- segsToStmts :: Stmt GhcRn body @@ -1908,7 +1908,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- then we have actually done some splitting. Otherwise it will go into -- an infinite loop (#14163). go lets indep bndrs ((L loc (BindStmt _ pat body bind_op fail_op), fvs): rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) && not (isStrictPattern pat) + | disjointNameSet bndrs fvs && not (isStrictPattern pat) = go lets ((L loc (BindStmt noExtField pat body bind_op fail_op), fvs) : indep) bndrs' rest where bndrs' = bndrs `unionNameSet` mkNameSet (collectPatBinders pat) @@ -1918,7 +1918,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- TODO: perhaps we shouldn't do this if there are any strict bindings, -- because we might be moving evaluation earlier. go lets indep bndrs ((L loc (LetStmt noExtField binds), fvs) : rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) + | disjointNameSet bndrs fvs = go ((L loc (LetStmt noExtField binds), fvs) : lets) indep bndrs rest go _ [] _ _ = Nothing go _ [_] _ _ = Nothing ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -533,7 +533,7 @@ closureGrowth expander sizer group abs_ids = go go (ClosureSk _ clo_fvs rhs) -- If no binder of the @group@ occurs free in the closure, the lifting -- won't have any effect on it and we can omit the recursive call. - | n_occs == 0 = 0 + | group `varSetDisjointDVarSet` clo_fvs' = 0 -- Otherwise, we account the cost of allocating the closure and add it to -- the closure growth of its RHS. | otherwise = mkIntWithInf cost + go rhs ===================================== compiler/GHC/Types/Module.hs ===================================== @@ -991,7 +991,7 @@ renameHoleUnitId' pkg_map env uid = IndefUnitId{ indefUnitIdComponentId = cid , indefUnitIdInsts = insts , indefUnitIdFreeHoles = fh }) - -> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env) + -> if disjointUdfmUfm (getUniqDSet fh) env then uid -- Functorially apply the substitution to the instantiation, -- then check the 'UnitInfoMap' to see if there is ===================================== compiler/GHC/Types/Name/Env.hs ===================================== @@ -140,7 +140,7 @@ delFromNameEnv x y = delFromUFM x y delListFromNameEnv x y = delListFromUFM x y filterNameEnv x y = filterUFM x y anyNameEnv f x = foldUFM ((||) . f) False x -disjointNameEnv x y = isNullUFM (intersectUFM x y) +disjointNameEnv x y = disjointUFM x y lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupNameEnv env n) ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -90,7 +90,7 @@ module GHC.Types.Name.Occurrence ( OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, extendOccSetList, unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, - isEmptyOccSet, intersectOccSet, intersectsOccSet, + isEmptyOccSet, intersectOccSet, intersectsOccSet, disjointOccSet, filterOccSet, -- * Tidying up @@ -452,6 +452,7 @@ minusOccSet :: OccSet -> OccSet -> OccSet elemOccSet :: OccName -> OccSet -> Bool isEmptyOccSet :: OccSet -> Bool intersectOccSet :: OccSet -> OccSet -> OccSet +disjointOccSet :: OccSet -> OccSet -> Bool intersectsOccSet :: OccSet -> OccSet -> Bool filterOccSet :: (OccName -> Bool) -> OccSet -> OccSet @@ -466,7 +467,8 @@ minusOccSet = minusUniqSet elemOccSet = elementOfUniqSet isEmptyOccSet = isEmptyUniqSet intersectOccSet = intersectUniqSets -intersectsOccSet s1 s2 = not (isEmptyOccSet (s1 `intersectOccSet` s2)) +disjointOccSet = disjointUniqSets +intersectsOccSet s1 s2 = not (s1 `disjointOccSet` s2) filterOccSet = filterUniqSet {- ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Types.Name.Set ( emptyNameSet, unitNameSet, mkNameSet, unionNameSet, unionNameSets, minusNameSet, elemNameSet, extendNameSet, extendNameSetList, delFromNameSet, delListFromNameSet, isEmptyNameSet, filterNameSet, - intersectsNameSet, intersectNameSet, + intersectsNameSet, disjointNameSet, intersectNameSet, nameSetAny, nameSetAll, nameSetElemsStable, -- * Free variables @@ -65,6 +65,7 @@ delListFromNameSet :: NameSet -> [Name] -> NameSet filterNameSet :: (Name -> Bool) -> NameSet -> NameSet intersectNameSet :: NameSet -> NameSet -> NameSet intersectsNameSet :: NameSet -> NameSet -> Bool +disjointNameSet :: NameSet -> NameSet -> Bool -- ^ True if there is a non-empty intersection. -- @s1 `intersectsNameSet` s2@ doesn't compute @s2@ if @s1@ is empty @@ -81,10 +82,11 @@ elemNameSet = elementOfUniqSet delFromNameSet = delOneFromUniqSet filterNameSet = filterUniqSet intersectNameSet = intersectUniqSets +disjointNameSet = disjointUniqSets delListFromNameSet set ns = foldl' delFromNameSet set ns -intersectsNameSet s1 s2 = not (isEmptyNameSet (s1 `intersectNameSet` s2)) +intersectsNameSet s1 s2 = not (s1 `disjointNameSet` s2) nameSetAny :: (Name -> Bool) -> NameSet -> Bool nameSetAny = uniqSetAny ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -319,13 +319,13 @@ udfmIntersectUFM (UDFM x i) y = UDFM (M.intersection x (ufmToIntMap y)) i -- a subset of elements from the left set, so `i` is a good upper bound. intersectsUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -intersectsUDFM x y = isNullUDFM (x `intersectUDFM` y) +intersectsUDFM x y = not (x `disjointUDFM` y) disjointUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -disjointUDFM (UDFM x _i) (UDFM y _j) = M.null (M.intersection x y) +disjointUDFM (UDFM x _i) (UDFM y _j) = M.disjoint x y disjointUdfmUfm :: UniqDFM elt -> UniqFM elt2 -> Bool -disjointUdfmUfm (UDFM x _i) y = M.null (M.intersection x (ufmToIntMap y)) +disjointUdfmUfm (UDFM x _i) y = M.disjoint x (ufmToIntMap y) minusUDFM :: UniqDFM elt1 -> UniqDFM elt2 -> UniqDFM elt1 minusUDFM (UDFM x i) (UDFM y _j) = UDFM (M.difference x y) i ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, + uniqDSetDisjointUniqSet, foldUniqDSet, elementOfUniqDSet, filterUniqDSet, @@ -98,6 +99,10 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) +uniqDSetDisjointUniqSet :: UniqDSet a -> UniqSet b -> Bool +uniqDSetDisjointUniqSet xs ys + = disjointUdfmUfm (getUniqDSet xs) (getUniqSet ys) + foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b foldUniqDSet c n (UniqDSet s) = foldUDFM c n s ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -241,7 +241,7 @@ intersectUFM_C intersectUFM_C f (UFM x) (UFM y) = UFM (M.intersectionWith f x y) disjointUFM :: UniqFM elt1 -> UniqFM elt2 -> Bool -disjointUFM (UFM x) (UFM y) = M.null (M.intersection x y) +disjointUFM (UFM x) (UFM y) = M.disjoint x y foldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a foldUFM k z (UFM m) = M.foldr k z m ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -27,6 +27,7 @@ module GHC.Types.Unique.Set ( unionUniqSets, unionManyUniqSets, minusUniqSet, uniqSetMinusUFM, intersectUniqSets, + disjointUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, elementOfUniqSet, @@ -105,6 +106,9 @@ minusUniqSet (UniqSet s) (UniqSet t) = UniqSet (minusUFM s t) intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a intersectUniqSets (UniqSet s) (UniqSet t) = UniqSet (intersectUFM s t) +disjointUniqSets :: UniqSet a -> UniqSet a -> Bool +disjointUniqSets (UniqSet s) (UniqSet t) = disjointUFM s t + restrictUniqSetToUFM :: UniqSet a -> UniqFM b -> UniqSet a restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -507,7 +507,7 @@ plusMaybeVarEnv_C = plusMaybeUFM_C delVarEnvList = delListFromUFM delVarEnv = delFromUFM minusVarEnv = minusUFM -intersectsVarEnv e1 e2 = not (isEmptyVarEnv (e1 `intersectUFM` e2)) +intersectsVarEnv e1 e2 = not (e1 `disjointUFM` e2) plusVarEnv = plusUFM plusVarEnvList = plusUFMList lookupVarEnv = lookupUFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -34,7 +34,7 @@ module GHC.Types.Var.Set ( elemDVarSet, dVarSetElems, subDVarSet, unionDVarSet, unionDVarSets, mapUnionDVarSet, intersectDVarSet, dVarSetIntersectVarSet, - intersectsDVarSet, disjointDVarSet, + intersectsDVarSet, disjointDVarSet, varSetDisjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, minusDVarSet, foldDVarSet, filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, @@ -274,6 +274,9 @@ dVarSetIntersectVarSet = uniqDSetIntersectUniqSet disjointDVarSet :: DVarSet -> DVarSet -> Bool disjointDVarSet s1 s2 = disjointUDFM (getUniqDSet s1) (getUniqDSet s2) +varSetDisjointDVarSet :: VarSet -> DVarSet -> Bool +varSetDisjointDVarSet vs dvs = uniqDSetDisjointUniqSet dvs vs + -- | True if non-empty intersection intersectsDVarSet :: DVarSet -> DVarSet -> Bool intersectsDVarSet s1 s2 = not (s1 `disjointDVarSet` s2) ===================================== compiler/ghc.cabal.in ===================================== @@ -66,7 +66,7 @@ Library bytestring >= 0.9 && < 0.11, binary == 0.8.*, time >= 1.4 && < 1.10, - containers >= 0.5 && < 0.7, + containers >= 0.6.2.1 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, template-haskell == 2.16.*, ===================================== compiler/iface/BuildTyCl.hs ===================================== @@ -164,8 +164,7 @@ mkDataConStupidTheta tycon arg_tys univ_tvs -- stupid theta, taken from the TyCon arg_tyvars = tyCoVarsOfTypes arg_tys - in_arg_tys pred = not $ isEmptyVarSet $ - tyCoVarsOfType pred `intersectVarSet` arg_tyvars + in_arg_tys pred = tyCoVarsOfType pred `intersectsVarSet` arg_tyvars ------------------------------------------------------ ===================================== compiler/typecheck/TcHoleErrors.hs ===================================== @@ -674,8 +674,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ctFreeVarSet = fvVarSet . tyCoFVsOfType . ctPred hole_fv_set = fvVarSet hole_fvs anyFVMentioned :: Ct -> Bool - anyFVMentioned ct = not $ isEmptyVarSet $ - ctFreeVarSet ct `intersectVarSet` hole_fv_set + anyFVMentioned ct = ctFreeVarSet ct `intersectsVarSet` hole_fv_set -- We filter out those constraints that have no variables (since -- they won't be solved by finding a type for the type variable -- representing the hole) and also other holes, since we're not ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -2415,7 +2415,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs is_floatable :: VarSet -> Ct -> Bool is_floatable skols ct - | isDerivedCt ct = not (tyCoVarsOfCt ct `intersectsVarSet` skols) + | isDerivedCt ct = tyCoVarsOfCt ct `disjointVarSet` skols | otherwise = not (ctEvId ct `elemVarSet` skols) add_captured_ev_ids :: Cts -> VarSet -> VarSet ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -103,9 +103,8 @@ documentationRules = do -- include toplevel html target unless we neither want -- haddocks nor html pages produced by sphinx. - ++ [ html | Set.size (doctargets `Set.intersection` - Set.fromList [Haddocks, SphinxHTML] - ) > 0 ] + ++ [ html | Haddocks `Set.member` doctargets + || SphinxHTML `Set.member` doctargets ] -- include archives for whatever targets remain from -- the --docs arguments we got. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2dd3c5479b0a060b35af0a480512cf1848df6cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2dd3c5479b0a060b35af0a480512cf1848df6cc You're receiving 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 1 08:09:36 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 04:09:36 -0400 Subject: [Git][ghc/ghc][wip/T16806] Use Data.IntMap.disjoint Message-ID: <5e844c40ee8fb_61673f8198ee100c21226b1@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: 9191ffd6 by Simon Jakobi at 2020-04-01T10:09:25+02:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 20 changed files: - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Module.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Set.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/ghc.cabal.in - compiler/iface/BuildTyCl.hs - compiler/typecheck/TcHoleErrors.hs - compiler/typecheck/TcSimplify.hs - hadrian/src/Rules/Documentation.hs Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -1173,7 +1173,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] is_flt_sc_arg var = isId var && not (isDeadBinder var) && isDictTy var_ty - && not (tyCoVarsOfType var_ty `intersectsVarSet` arg_set) + && tyCoVarsOfType var_ty `disjointVarSet` arg_set where var_ty = idType var @@ -2489,7 +2489,7 @@ filterCalls (CIS fn call_bag) dbs = extendVarSetList so_far (bindersOf db) | otherwise = so_far - ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) + ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set ---------------------- splitDictBinds :: Bag DictBind -> IdSet -> (Bag DictBind, Bag DictBind, IdSet) @@ -2519,7 +2519,7 @@ deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails deleteCallsMentioning bs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` bs) + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs deleteCallsFor :: [Id] -> CallDetails -> CallDetails -- Remove calls *for* bs ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -383,8 +383,8 @@ extendTCvSubstList subst tvs tys unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst -- Works when the ranges are disjoint unionTCvSubst (TCvSubst in_scope1 tenv1 cenv1) (TCvSubst in_scope2 tenv2 cenv2) - = ASSERT( not (tenv1 `intersectsVarEnv` tenv2) - && not (cenv1 `intersectsVarEnv` cenv2) ) + = ASSERT( tenv1 `disjointVarEnv` tenv2 + && cenv1 `disjointVarEnv` cenv2 ) TCvSubst (in_scope1 `unionInScope` in_scope2) (tenv1 `plusVarEnv` tenv2) (cenv1 `plusVarEnv` cenv2) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2112,7 +2112,7 @@ isValidJoinPointType arity ty where valid_under tvs arity ty | arity == 0 - = isEmptyVarSet (tvs `intersectVarSet` tyCoVarsOfType ty) + = tvs `disjointVarSet` tyCoVarsOfType ty | Just (t, ty') <- splitForAllTy_maybe ty = valid_under (tvs `extendVarSet` t) (arity-1) ty' | Just (_, res_ty) <- splitFunTy_maybe ty ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -1350,7 +1350,7 @@ glomSegments ctxt ((defs,uses,fwds,stmt) : segs) = (reverse yeses, reverse noes) where (noes, yeses) = span not_needed (reverse dus) - not_needed (defs,_,_,_) = not (intersectsNameSet defs uses) + not_needed (defs,_,_,_) = disjointNameSet defs uses ---------------------------------------------------- segsToStmts :: Stmt GhcRn body @@ -1908,7 +1908,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- then we have actually done some splitting. Otherwise it will go into -- an infinite loop (#14163). go lets indep bndrs ((L loc (BindStmt _ pat body bind_op fail_op), fvs): rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) && not (isStrictPattern pat) + | disjointNameSet bndrs fvs && not (isStrictPattern pat) = go lets ((L loc (BindStmt noExtField pat body bind_op fail_op), fvs) : indep) bndrs' rest where bndrs' = bndrs `unionNameSet` mkNameSet (collectPatBinders pat) @@ -1918,7 +1918,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- TODO: perhaps we shouldn't do this if there are any strict bindings, -- because we might be moving evaluation earlier. go lets indep bndrs ((L loc (LetStmt noExtField binds), fvs) : rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) + | disjointNameSet bndrs fvs = go ((L loc (LetStmt noExtField binds), fvs) : lets) indep bndrs rest go _ [] _ _ = Nothing go _ [_] _ _ = Nothing ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -533,10 +533,10 @@ closureGrowth expander sizer group abs_ids = go go (ClosureSk _ clo_fvs rhs) -- If no binder of the @group@ occurs free in the closure, the lifting -- won't have any effect on it and we can omit the recursive call. - | n_occs == 0 = 0 + | group `varSetDisjointDVarSet` clo_fvs' = 0 -- Otherwise, we account the cost of allocating the closure and add it to -- the closure growth of its RHS. - | otherwise = mkIntWithInf cost + go rhs + | otherwise = mkIntWithInf cost + go rhs where n_occs = sizeDVarSet (clo_fvs' `dVarSetIntersectVarSet` group) -- What we close over considering prior lifting decisions ===================================== compiler/GHC/Types/Module.hs ===================================== @@ -991,7 +991,7 @@ renameHoleUnitId' pkg_map env uid = IndefUnitId{ indefUnitIdComponentId = cid , indefUnitIdInsts = insts , indefUnitIdFreeHoles = fh }) - -> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env) + -> if disjointUdfmUfm (getUniqDSet fh) env then uid -- Functorially apply the substitution to the instantiation, -- then check the 'UnitInfoMap' to see if there is ===================================== compiler/GHC/Types/Name/Env.hs ===================================== @@ -140,7 +140,7 @@ delFromNameEnv x y = delFromUFM x y delListFromNameEnv x y = delListFromUFM x y filterNameEnv x y = filterUFM x y anyNameEnv f x = foldUFM ((||) . f) False x -disjointNameEnv x y = isNullUFM (intersectUFM x y) +disjointNameEnv x y = disjointUFM x y lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupNameEnv env n) ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -90,7 +90,7 @@ module GHC.Types.Name.Occurrence ( OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, extendOccSetList, unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, - isEmptyOccSet, intersectOccSet, intersectsOccSet, + isEmptyOccSet, intersectOccSet, intersectsOccSet, disjointOccSet, filterOccSet, -- * Tidying up @@ -452,6 +452,7 @@ minusOccSet :: OccSet -> OccSet -> OccSet elemOccSet :: OccName -> OccSet -> Bool isEmptyOccSet :: OccSet -> Bool intersectOccSet :: OccSet -> OccSet -> OccSet +disjointOccSet :: OccSet -> OccSet -> Bool intersectsOccSet :: OccSet -> OccSet -> Bool filterOccSet :: (OccName -> Bool) -> OccSet -> OccSet @@ -466,7 +467,8 @@ minusOccSet = minusUniqSet elemOccSet = elementOfUniqSet isEmptyOccSet = isEmptyUniqSet intersectOccSet = intersectUniqSets -intersectsOccSet s1 s2 = not (isEmptyOccSet (s1 `intersectOccSet` s2)) +disjointOccSet = disjointUniqSets +intersectsOccSet s1 s2 = not (s1 `disjointOccSet` s2) filterOccSet = filterUniqSet {- ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Types.Name.Set ( emptyNameSet, unitNameSet, mkNameSet, unionNameSet, unionNameSets, minusNameSet, elemNameSet, extendNameSet, extendNameSetList, delFromNameSet, delListFromNameSet, isEmptyNameSet, filterNameSet, - intersectsNameSet, intersectNameSet, + intersectsNameSet, disjointNameSet, intersectNameSet, nameSetAny, nameSetAll, nameSetElemsStable, -- * Free variables @@ -65,6 +65,7 @@ delListFromNameSet :: NameSet -> [Name] -> NameSet filterNameSet :: (Name -> Bool) -> NameSet -> NameSet intersectNameSet :: NameSet -> NameSet -> NameSet intersectsNameSet :: NameSet -> NameSet -> Bool +disjointNameSet :: NameSet -> NameSet -> Bool -- ^ True if there is a non-empty intersection. -- @s1 `intersectsNameSet` s2@ doesn't compute @s2@ if @s1@ is empty @@ -81,10 +82,11 @@ elemNameSet = elementOfUniqSet delFromNameSet = delOneFromUniqSet filterNameSet = filterUniqSet intersectNameSet = intersectUniqSets +disjointNameSet = disjointUniqSets delListFromNameSet set ns = foldl' delFromNameSet set ns -intersectsNameSet s1 s2 = not (isEmptyNameSet (s1 `intersectNameSet` s2)) +intersectsNameSet s1 s2 = not (s1 `disjointNameSet` s2) nameSetAny :: (Name -> Bool) -> NameSet -> Bool nameSetAny = uniqSetAny ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -319,13 +319,13 @@ udfmIntersectUFM (UDFM x i) y = UDFM (M.intersection x (ufmToIntMap y)) i -- a subset of elements from the left set, so `i` is a good upper bound. intersectsUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -intersectsUDFM x y = isNullUDFM (x `intersectUDFM` y) +intersectsUDFM x y = not (x `disjointUDFM` y) disjointUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -disjointUDFM (UDFM x _i) (UDFM y _j) = M.null (M.intersection x y) +disjointUDFM (UDFM x _i) (UDFM y _j) = M.disjoint x y disjointUdfmUfm :: UniqDFM elt -> UniqFM elt2 -> Bool -disjointUdfmUfm (UDFM x _i) y = M.null (M.intersection x (ufmToIntMap y)) +disjointUdfmUfm (UDFM x _i) y = M.disjoint x (ufmToIntMap y) minusUDFM :: UniqDFM elt1 -> UniqDFM elt2 -> UniqDFM elt1 minusUDFM (UDFM x i) (UDFM y _j) = UDFM (M.difference x y) i ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,6 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, + uniqDSetDisjointUniqSet, foldUniqDSet, elementOfUniqDSet, filterUniqDSet, @@ -98,6 +99,10 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) +uniqDSetDisjointUniqSet :: UniqDSet a -> UniqSet b -> Bool +uniqDSetDisjointUniqSet xs ys + = disjointUdfmUfm (getUniqDSet xs) (getUniqSet ys) + foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b foldUniqDSet c n (UniqDSet s) = foldUDFM c n s ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -241,7 +241,7 @@ intersectUFM_C intersectUFM_C f (UFM x) (UFM y) = UFM (M.intersectionWith f x y) disjointUFM :: UniqFM elt1 -> UniqFM elt2 -> Bool -disjointUFM (UFM x) (UFM y) = M.null (M.intersection x y) +disjointUFM (UFM x) (UFM y) = M.disjoint x y foldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a foldUFM k z (UFM m) = M.foldr k z m ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -27,6 +27,7 @@ module GHC.Types.Unique.Set ( unionUniqSets, unionManyUniqSets, minusUniqSet, uniqSetMinusUFM, intersectUniqSets, + disjointUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, elementOfUniqSet, @@ -105,6 +106,9 @@ minusUniqSet (UniqSet s) (UniqSet t) = UniqSet (minusUFM s t) intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a intersectUniqSets (UniqSet s) (UniqSet t) = UniqSet (intersectUFM s t) +disjointUniqSets :: UniqSet a -> UniqSet a -> Bool +disjointUniqSets (UniqSet s) (UniqSet t) = disjointUFM s t + restrictUniqSetToUFM :: UniqSet a -> UniqFM b -> UniqSet a restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -507,7 +507,7 @@ plusMaybeVarEnv_C = plusMaybeUFM_C delVarEnvList = delListFromUFM delVarEnv = delFromUFM minusVarEnv = minusUFM -intersectsVarEnv e1 e2 = not (isEmptyVarEnv (e1 `intersectUFM` e2)) +intersectsVarEnv e1 e2 = not (e1 `disjointUFM` e2) plusVarEnv = plusUFM plusVarEnvList = plusUFMList lookupVarEnv = lookupUFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -34,7 +34,7 @@ module GHC.Types.Var.Set ( elemDVarSet, dVarSetElems, subDVarSet, unionDVarSet, unionDVarSets, mapUnionDVarSet, intersectDVarSet, dVarSetIntersectVarSet, - intersectsDVarSet, disjointDVarSet, + intersectsDVarSet, disjointDVarSet, varSetDisjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, minusDVarSet, foldDVarSet, filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, @@ -274,6 +274,9 @@ dVarSetIntersectVarSet = uniqDSetIntersectUniqSet disjointDVarSet :: DVarSet -> DVarSet -> Bool disjointDVarSet s1 s2 = disjointUDFM (getUniqDSet s1) (getUniqDSet s2) +varSetDisjointDVarSet :: VarSet -> DVarSet -> Bool +varSetDisjointDVarSet vs dvs = uniqDSetDisjointUniqSet dvs vs + -- | True if non-empty intersection intersectsDVarSet :: DVarSet -> DVarSet -> Bool intersectsDVarSet s1 s2 = not (s1 `disjointDVarSet` s2) ===================================== compiler/ghc.cabal.in ===================================== @@ -66,7 +66,7 @@ Library bytestring >= 0.9 && < 0.11, binary == 0.8.*, time >= 1.4 && < 1.10, - containers >= 0.5 && < 0.7, + containers >= 0.6.2.1 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, template-haskell == 2.16.*, ===================================== compiler/iface/BuildTyCl.hs ===================================== @@ -164,8 +164,7 @@ mkDataConStupidTheta tycon arg_tys univ_tvs -- stupid theta, taken from the TyCon arg_tyvars = tyCoVarsOfTypes arg_tys - in_arg_tys pred = not $ isEmptyVarSet $ - tyCoVarsOfType pred `intersectVarSet` arg_tyvars + in_arg_tys pred = tyCoVarsOfType pred `intersectsVarSet` arg_tyvars ------------------------------------------------------ ===================================== compiler/typecheck/TcHoleErrors.hs ===================================== @@ -674,8 +674,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ctFreeVarSet = fvVarSet . tyCoFVsOfType . ctPred hole_fv_set = fvVarSet hole_fvs anyFVMentioned :: Ct -> Bool - anyFVMentioned ct = not $ isEmptyVarSet $ - ctFreeVarSet ct `intersectVarSet` hole_fv_set + anyFVMentioned ct = ctFreeVarSet ct `intersectsVarSet` hole_fv_set -- We filter out those constraints that have no variables (since -- they won't be solved by finding a type for the type variable -- representing the hole) and also other holes, since we're not ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -2415,7 +2415,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs is_floatable :: VarSet -> Ct -> Bool is_floatable skols ct - | isDerivedCt ct = not (tyCoVarsOfCt ct `intersectsVarSet` skols) + | isDerivedCt ct = tyCoVarsOfCt ct `disjointVarSet` skols | otherwise = not (ctEvId ct `elemVarSet` skols) add_captured_ev_ids :: Cts -> VarSet -> VarSet ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -103,9 +103,8 @@ documentationRules = do -- include toplevel html target unless we neither want -- haddocks nor html pages produced by sphinx. - ++ [ html | Set.size (doctargets `Set.intersection` - Set.fromList [Haddocks, SphinxHTML] - ) > 0 ] + ++ [ html | Haddocks `Set.member` doctargets + || SphinxHTML `Set.member` doctargets ] -- include archives for whatever targets remain from -- the --docs arguments we got. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9191ffd6d705efb9ed7300149f972d026b6d89ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9191ffd6d705efb9ed7300149f972d026b6d89ef You're receiving 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 1 09:18:03 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 01 Apr 2020 05:18:03 -0400 Subject: [Git][ghc/ghc][wip/T17966] Major improvements to the specialiser Message-ID: <5e845c4b170ff_61675cefcac2135355@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17966 at Glasgow Haskell Compiler / GHC Commits: a8b2ae43 by Simon Peyton Jones at 2020-04-01T10:16:56+01:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 15 changed files: - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/Binds.hs - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/Makefile - + testsuite/tests/simplCore/should_compile/T17810.hs - + testsuite/tests/simplCore/should_compile/T17810a.hs - + testsuite/tests/simplCore/should_compile/T17930.hs - + testsuite/tests/simplCore/should_compile/T17930.stderr - + testsuite/tests/simplCore/should_compile/T17966.hs - + testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_compile/spec004.hs - + testsuite/tests/simplCore/should_compile/spec004.stderr Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Core.Predicate import GHC.Types.Module( Module, HasModule(..) ) import GHC.Core.Coercion( Coercion ) import GHC.Core.Op.Monad -import qualified GHC.Core.Subst +import qualified GHC.Core.Subst as Core import GHC.Core.Unfold import GHC.Types.Var ( isLocalVar ) import GHC.Types.Var.Set @@ -30,13 +30,15 @@ import GHC.Types.Var.Env import GHC.Core import GHC.Core.Rules import GHC.Core.SimpleOpt ( collectBindersPushingCo ) -import GHC.Core.Utils ( exprIsTrivial, mkCast, exprType ) +import GHC.Core.Utils ( exprIsTrivial, getIdFromTrivialExpr_maybe + , mkCast, exprType ) import GHC.Core.FVs import GHC.Core.Arity ( etaExpandToJoinPointRule ) import GHC.Types.Unique.Supply import GHC.Types.Name import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import Maybes ( mapMaybe, isJust ) +import TysPrim ( voidPrimTy ) +import Maybes ( mapMaybe, maybeToList, isJust ) import MonadUtils ( foldlM ) import GHC.Types.Basic import GHC.Driver.Types @@ -607,7 +609,7 @@ specProgram guts@(ModGuts { mg_module = this_mod -- accidentally re-use a unique that's already in use -- Easiest thing is to do it all at once, as if all the top-level -- decls were mutually recursive - top_env = SE { se_subst = GHC.Core.Subst.mkEmptySubst $ mkInScopeSet $ mkVarSet $ + top_env = SE { se_subst = Core.mkEmptySubst $ mkInScopeSet $ mkVarSet $ bindersOfBinds binds , se_interesting = emptyVarSet } @@ -637,189 +639,12 @@ bitten by such instances to revert to the pre-7.10 behavior. See #10491 -} --- | An argument that we might want to specialise. --- See Note [Specialising Calls] for the nitty gritty details. -data SpecArg - = - -- | Type arguments that should be specialised, due to appearing - -- free in the type of a 'SpecDict'. - SpecType Type - -- | Type arguments that should remain polymorphic. - | UnspecType - -- | Dictionaries that should be specialised. - | SpecDict DictExpr - -- | Value arguments that should not be specialised. - | UnspecArg - -instance Outputable SpecArg where - ppr (SpecType t) = text "SpecType" <+> ppr t - ppr UnspecType = text "UnspecType" - ppr (SpecDict d) = text "SpecDict" <+> ppr d - ppr UnspecArg = text "UnspecArg" - -getSpecDicts :: [SpecArg] -> [DictExpr] -getSpecDicts = mapMaybe go - where - go (SpecDict d) = Just d - go _ = Nothing - -getSpecTypes :: [SpecArg] -> [Type] -getSpecTypes = mapMaybe go - where - go (SpecType t) = Just t - go _ = Nothing - -isUnspecArg :: SpecArg -> Bool -isUnspecArg UnspecArg = True -isUnspecArg UnspecType = True -isUnspecArg _ = False - -isValueArg :: SpecArg -> Bool -isValueArg UnspecArg = True -isValueArg (SpecDict _) = True -isValueArg _ = False - --- | Given binders from an original function 'f', and the 'SpecArg's --- corresponding to its usage, compute everything necessary to build --- a specialisation. --- --- We will use a running example. Consider the function --- --- foo :: forall a b. Eq a => Int -> blah --- foo @a @b dEqA i = blah --- --- which is called with the 'CallInfo' --- --- [SpecType T1, UnspecType, SpecDict dEqT1, UnspecArg] --- --- We'd eventually like to build the RULE --- --- RULE "SPEC foo @T1 _" --- forall @a @b (dEqA' :: Eq a). --- foo @T1 @b dEqA' = $sfoo @b --- --- and the specialisation '$sfoo' --- --- $sfoo :: forall b. Int -> blah --- $sfoo @b = \i -> SUBST[a->T1, dEqA->dEqA'] blah --- --- The cases for 'specHeader' below are presented in the same order as this --- running example. The result of 'specHeader' for this example is as follows: --- --- ( -- Returned arguments --- env + [a -> T1, deqA -> dEqA'] --- , [] --- --- -- RULE helpers --- , [b, dx', i] --- , [T1, b, dx', i] --- --- -- Specialised function helpers --- , [b, i] --- , [dx] --- , [T1, b, dx_spec, i] --- ) -specHeader - :: SpecEnv - -> [CoreBndr] -- The binders from the original function 'f' - -> [SpecArg] -- From the CallInfo - -> SpecM ( -- Returned arguments - SpecEnv -- Substitution to apply to the body of 'f' - , [CoreBndr] -- All the remaining unspecialised args from the original function 'f' - - -- RULE helpers - , [CoreBndr] -- Binders for the RULE - , [CoreArg] -- Args for the LHS of the rule - - -- Specialised function helpers - , [CoreBndr] -- Binders for $sf - , [DictBind] -- Auxiliary dictionary bindings - , [CoreExpr] -- Specialised arguments for unfolding - ) - --- We want to specialise on type 'T1', and so we must construct a substitution --- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding --- details. -specHeader env (bndr : bndrs) (SpecType t : args) - = do { let env' = extendTvSubstList env [(bndr, t)] - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , rule_bs - , Type t : rule_es - , bs' - , dx - , Type t : spec_args - ) - } - --- Next we have a type that we don't want to specialise. We need to perform --- a substitution on it (in case the type refers to 'a'). Additionally, we need --- to produce a binder, LHS argument and RHS argument for the resulting rule, --- /and/ a binder for the specialised body. -specHeader env (bndr : bndrs) (UnspecType : args) - = do { let (env', bndr') = substBndr env bndr - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , bndr' : rule_bs - , varToCoreExpr bndr' : rule_es - , bndr' : bs' - , dx - , varToCoreExpr bndr' : spec_args - ) - } - --- Next we want to specialise the 'Eq a' dict away. We need to construct --- a wildcard binder to match the dictionary (See Note [Specialising Calls] for --- the nitty-gritty), as a LHS rule and unfolding details. -specHeader env (bndr : bndrs) (SpecDict d : args) - = do { inst_dict_id <- newDictBndr env bndr - ; let (rhs_env2, dx_binds, spec_dict_args') - = bindAuxiliaryDicts env [bndr] [d] [inst_dict_id] - ; (env', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader rhs_env2 bndrs args - ; pure ( env' - , unused_bndrs - -- See Note [Evidence foralls] - , exprFreeIdsList (varToCoreExpr inst_dict_id) ++ rule_bs - , varToCoreExpr inst_dict_id : rule_es - , bs' - , dx_binds ++ dx - , spec_dict_args' ++ spec_args - ) - } - --- Finally, we have the unspecialised argument 'i'. We need to produce --- a binder, LHS and RHS argument for the RULE, and a binder for the --- specialised body. --- --- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is --- why 'i' doesn't appear in our RULE above. But we have no guarantee that --- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so --- this case must be here. -specHeader env (bndr : bndrs) (UnspecArg : args) - = do { let (env', bndr') = substBndr env bndr - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , bndr' : rule_bs - , varToCoreExpr bndr' : rule_es - , bndr' : bs' - , dx - , varToCoreExpr bndr' : spec_args - ) - } - --- Return all remaining binders from the original function. These have the --- invariant that they should all correspond to unspecialised arguments, so --- it's safe to stop processing at this point. -specHeader env bndrs [] = pure (env, bndrs, [], [], [], [], []) -specHeader env [] _ = pure (env, [], [], [], [], [], []) +{- ********************************************************************* +* * + Specialising imported functions +* * +********************************************************************* -} -- | Specialise a set of calls to imported bindings specImports :: DynFlags @@ -1036,7 +861,7 @@ Avoiding this recursive specialisation loop is the reason for the -} data SpecEnv - = SE { se_subst :: GHC.Core.Subst.Subst + = SE { se_subst :: Core.Subst -- We carry a substitution down: -- a) we must clone any binding that might float outwards, -- to avoid name clashes @@ -1050,8 +875,14 @@ data SpecEnv -- See Note [Interesting dictionary arguments] } +instance Outputable SpecEnv where + ppr (SE { se_subst = subst, se_interesting = interesting }) + = text "SE" <+> braces (sep $ punctuate comma + [ text "subst =" <+> ppr subst + , text "interesting =" <+> ppr interesting ]) + specVar :: SpecEnv -> Id -> CoreExpr -specVar env v = GHC.Core.Subst.lookupIdSubst (text "specVar") (se_subst env) v +specVar env v = Core.lookupIdSubst (text "specVar") (se_subst env) v specExpr :: SpecEnv -> CoreExpr -> SpecM (CoreExpr, UsageDetails) @@ -1081,12 +912,10 @@ specExpr env expr@(App {}) go other _ = specExpr env other ---------------- Lambda/case require dumping of usage details -------------------- -specExpr env e@(Lam _ _) = do - (body', uds) <- specExpr env' body - let (free_uds, dumped_dbs) = dumpUDs bndrs' uds - return (mkLams bndrs' (wrapDictBindsE dumped_dbs body'), free_uds) +specExpr env e@(Lam {}) + = specLam env' bndrs' body where - (bndrs, body) = collectBinders e + (bndrs, body) = collectBinders e (env', bndrs') = substBndrs env bndrs -- More efficient to collect a group of binders together all at once -- and we don't want to split a lambda group with dumped bindings @@ -1112,6 +941,18 @@ specExpr env (Let bind body) -- All done ; return (foldr Let body' binds', uds) } +-------------- +specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails) +-- The binders have been substituted, but the body has not +specLam env bndrs body + | null bndrs + = specExpr env body + | otherwise + = do { (body', uds) <- specExpr env body + ; let (free_uds, dumped_dbs) = dumpUDs bndrs uds + ; return (mkLams bndrs (wrapDictBindsE dumped_dbs body'), free_uds) } + +-------------- specTickish :: SpecEnv -> Tickish Id -> Tickish Id specTickish env (Breakpoint ix ids) = Breakpoint ix [ id' | id <- ids, Var id' <- [specVar env id]] @@ -1119,6 +960,7 @@ specTickish env (Breakpoint ix ids) -- should never happen, but it's harmless to drop them anyway. specTickish _ other_tickish = other_tickish +-------------- specCase :: SpecEnv -> CoreExpr -- Scrutinee, already done -> Id -> [CoreAlt] @@ -1144,7 +986,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] subst_prs = (case_bndr, Var case_bndr_flt) : [ (arg, Var sc_flt) | (arg, Just sc_flt) <- args `zip` mb_sc_flts ] - env_rhs' = env_rhs { se_subst = GHC.Core.Subst.extendIdSubstList (se_subst env_rhs) subst_prs + env_rhs' = env_rhs { se_subst = Core.extendIdSubstList (se_subst env_rhs) subst_prs , se_interesting = se_interesting env_rhs `extendVarSetList` (case_bndr_flt : sc_args_flt) } @@ -1241,7 +1083,13 @@ specBind :: SpecEnv -- Use this for RHSs -- No calls for binders of this bind specBind rhs_env (NonRec fn rhs) body_uds = do { (rhs', rhs_uds) <- specExpr rhs_env rhs - ; (fn', spec_defns, body_uds1) <- specDefn rhs_env body_uds fn rhs + + ; let zapped_fn = zapIdDemandInfo fn + -- We zap the demand info because the binding may float, + -- which would invaidate the demand info (see #17810 for example). + -- Destroying demand info is not terrible; specialisation is + -- always followed soon by demand analysis. + ; (fn', spec_defns, body_uds1) <- specDefn rhs_env body_uds zapped_fn rhs ; let pairs = spec_defns ++ [(fn', rhs')] -- fn' mentions the spec_defns in its rules, @@ -1361,8 +1209,7 @@ type SpecInfo = ( [CoreRule] -- Specialisation rules specCalls mb_mod env existing_rules calls_for_me fn rhs -- The first case is the interesting one - | callSpecArity pis <= fn_arity -- See Note [Specialisation Must Preserve Sharing] - && notNull calls_for_me -- And there are some calls to specialise + | notNull calls_for_me -- And there are some calls to specialise && not (isNeverActive (idInlineActivation fn)) -- Don't specialise NOINLINE things -- See Note [Auto-specialisation and RULES] @@ -1382,27 +1229,22 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- pprTrace "specDefn: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) where - _trace_doc = sep [ ppr rhs_tyvars, ppr rhs_bndrs - , ppr (idInlineActivation fn) ] - - fn_type = idType fn - fn_arity = idArity fn - fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here - pis = fst $ splitPiTys fn_type - theta = getTheta pis - n_dicts = length theta - inl_prag = idInlinePragma fn - inl_act = inlinePragmaActivation inl_prag - is_local = isLocalId fn + _trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] + + fn_type = idType fn + fn_arity = idArity fn + fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here + inl_prag = idInlinePragma fn + inl_act = inlinePragmaActivation inl_prag + is_local = isLocalId fn -- Figure out whether the function has an INLINE pragma -- See Note [Inline specialisations] - (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs - -- See Note [Account for casts in binding] - rhs_tyvars = filter isTyVar rhs_bndrs + (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs + -- See Note [Account for casts in binding] - in_scope = GHC.Core.Subst.substInScope (se_subst env) + in_scope = Core.substInScope (se_subst env) already_covered :: DynFlags -> [CoreRule] -> [CoreExpr] -> Bool already_covered dflags new_rules args -- Note [Specialisations already covered] @@ -1417,38 +1259,43 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs spec_call :: SpecInfo -- Accumulating parameter -> CallInfo -- Call instance -> SpecM SpecInfo - spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) - (CI { ci_key = call_args, ci_arity = call_arity }) - = ASSERT(call_arity <= fn_arity) - - -- See Note [Specialising Calls] - do { (rhs_env2, unused_bndrs, rule_bndrs, rule_args, unspec_bndrs, dx_binds, spec_args) - <- specHeader env rhs_bndrs $ dropWhileEndLE isUnspecArg call_args - ; let rhs_body' = mkLams unused_bndrs rhs_body + spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) (CI { ci_key = call_args }) + = -- See Note [Specialising Calls] + do { ( useful, rhs_env2, leftover_bndrs + , rule_bndrs, rule_lhs_args + , spec_bndrs, dx_binds, spec_args) <- specHeader env rhs_bndrs call_args + ; dflags <- getDynFlags - ; if already_covered dflags rules_acc rule_args + ; if not useful -- No useful specialisation + || already_covered dflags rules_acc rule_lhs_args then return spec_acc else -- pprTrace "spec_call" (vcat [ ppr _call_info, ppr fn, ppr rhs_dict_ids -- , text "rhs_env2" <+> ppr (se_subst rhs_env2) -- , ppr dx_binds ]) $ - do - { -- Figure out the type of the specialised function - let body = mkLams unspec_bndrs rhs_body' - body_ty = substTy rhs_env2 $ exprType body - (lam_extra_args, app_args) -- See Note [Specialisations Must Be Lifted] - | isUnliftedType body_ty -- C.f. GHC.Core.Op.WorkWrap.Lib.mkWorkerArgs - , not (isJoinId fn) - = ([voidArgId], voidPrimId : unspec_bndrs) - | otherwise = ([], unspec_bndrs) - join_arity_change = length app_args - length rule_args + do { -- Run the specialiser on the specialised RHS + -- The "1" suffix is before we maybe add the void arg + ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs ++ leftover_bndrs) rhs_body + ; let spec_fn_ty1 = exprType spec_rhs1 + + -- Maybe add a void arg to the specialised function, + -- to avoid unlifted bindings + -- See Note [Specialisations Must Be Lifted] + -- C.f. GHC.Core.Op.WorkWrap.Lib.mkWorkerArgs + add_void_arg = isUnliftedType spec_fn_ty1 && not (isJoinId fn) + (spec_rhs, spec_fn_ty, rule_rhs_args) + | add_void_arg = ( Lam voidArgId spec_rhs1 + , mkVisFunTy voidPrimTy spec_fn_ty1 + , voidPrimId : spec_bndrs) + | otherwise = (spec_rhs1, spec_fn_ty1, spec_bndrs) + + arity_decr = count isValArg rule_lhs_args - count isId rule_rhs_args + join_arity_decr = length rule_lhs_args - length rule_rhs_args spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity + join_arity_change) + = Just (orig_join_arity - join_arity_decr) | otherwise = Nothing - ; (spec_rhs, rhs_uds) <- specExpr rhs_env2 (mkLams lam_extra_args body) - ; let spec_id_ty = exprType spec_rhs - ; spec_f <- newSpecIdSM fn spec_id_ty spec_join_arity + ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity ; this_mod <- getModule ; let -- The rule to put in the function's specialisation is: @@ -1476,13 +1323,12 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs inl_act -- Note [Auto-specialisation and RULES] (idName fn) rule_bndrs - rule_args - (mkVarApps (Var spec_f) app_args) + rule_lhs_args + (mkVarApps (Var spec_fn) rule_rhs_args) spec_rule = case isJoinId_maybe fn of - Just join_arity -> etaExpandToJoinPointRule join_arity - rule_wout_eta + Just join_arity -> etaExpandToJoinPointRule join_arity rule_wout_eta Nothing -> rule_wout_eta -- Add the { d1' = dx1; d2' = dx2 } usage stuff @@ -1501,7 +1347,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs = (inl_prag { inl_inline = NoUserInline }, noUnfolding) | otherwise - = (inl_prag, specUnfolding dflags unspec_bndrs spec_app n_dicts fn_unf) + = (inl_prag, specUnfolding dflags fn spec_bndrs spec_app arity_decr fn_unf) spec_app e = e `mkApps` spec_args @@ -1509,13 +1355,14 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- Adding arity information just propagates it a bit faster -- See Note [Arity decrease] in GHC.Core.Op.Simplify -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_f - spec_f_w_arity = spec_f `setIdArity` max 0 (fn_arity - n_dicts) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity - - _rule_trace_doc = vcat [ ppr spec_f, ppr fn_type, ppr spec_id_ty + -- So if f has INLINE[1] so does spec_fn + spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) + `setInlinePragma` spec_inl_prag + `setIdUnfolding` spec_unf + `asJoinId_maybe` spec_join_arity + + _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type + , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty , ppr rhs_bndrs, ppr call_args , ppr spec_rule ] @@ -1574,33 +1421,44 @@ preserve laziness. Note [Specialising Calls] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose we have a function: +Suppose we have a function with a complicated type: - f :: Int -> forall a b c. (Foo a, Foo c) => Bar -> Qux - f = \x -> /\ a b c -> \d1 d2 bar -> rhs + f :: forall a b c. Int -> Eq a => Show b => c -> Blah + f @a @b @c i dEqA dShowA x = blah and suppose it is called at: - f 7 @T1 @T2 @T3 dFooT1 dFooT3 bar + f 7 @T1 @T2 @T3 dEqT1 ($dfShow dShowT2) t3 -This call is described as a 'CallInfo' whose 'ci_key' is +This call is described as a 'CallInfo' whose 'ci_key' is: - [ UnspecArg, SpecType T1, UnspecType, SpecType T3, SpecDict dFooT1 - , SpecDict dFooT3, UnspecArg ] + [ SpecType T1, SpecType T2, UnspecType, UnspecArg, SpecDict dEqT1 + , SpecDict ($dfShow dShowT2), UnspecArg ] -Why are 'a' and 'c' identified as 'SpecType', while 'b' is 'UnspecType'? +Why are 'a' and 'b' identified as 'SpecType', while 'c' is 'UnspecType'? Because we must specialise the function on type variables that appear free in its *dictionary* arguments; but not on type variables that do not appear in any dictionaries, i.e. are fully polymorphic. Because this call has dictionaries applied, we'd like to specialise the call on any type argument that appears free in those dictionaries. -In this case, those are (a ~ T1, c ~ T3). +In this case, those are [a :-> T1, b :-> T2]. + +We also need to substitute the dictionary binders with their +specialised dictionaries. The simplest substitution would be +[dEqA :-> dEqT1, dShowA :-> $dfShow dShowT2], but this duplicates +work, since `$dfShow dShowT2` is a function application. Therefore, we +also want to *float the dictionary out* (via bindAuxiliaryDict), +creating a new dict binding + + dShow1 = $dfShow dShowT2 -As a result, we'd like to generate a function: +and the substitution [dEqA :-> dEqT1, dShowA :-> dShow1]. - $sf :: Int -> forall b. Bar -> Qux - $sf = SUBST[a->T1, c->T3, d1->d1', d2->d2'] (\x -> /\ b -> \bar -> rhs) +With the substitutions in hand, we can generate a specialised function: + + $sf :: forall c. Int -> c -> Blah + $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah) Note that the substitution is applied to the whole thing. This is convenient, but just slightly fragile. Notably: @@ -1608,20 +1466,71 @@ convenient, but just slightly fragile. Notably: We must construct a rewrite rule: - RULE "SPEC f @T1 _ @T3" - forall (x :: Int) (@b :: Type) (d1' :: Foo T1) (d2' :: Foo T3). - f x @T1 @b @T3 d1' d2' = $sf x @b + RULE "SPEC f @T1 @T2 _" + forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2). + f @T1 @T2 @c i d1 d2 = $sf @c i -In the rule, d1' and d2' are just wildcards, not used in the RHS. Note -additionally that 'bar' isn't captured by this rule --- we bind only +In the rule, d1 and d2 are just wildcards, not used in the RHS. Note +additionally that 'x' isn't captured by this rule --- we bind only enough etas in order to capture all of the *specialised* arguments. -Finally, we must also construct the usage-details +Note [Drop dead args from specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, it’s possible some of the arguments may +actually be dead. For example, consider: + + f :: forall a. () -> Show a => a -> String + f x y = show y ++ "!" + +We might generate the following CallInfo for `f @Int`: + + [SpecType Int, UnspecArg, SpecDict $dShowInt, UnspecArg] + +Normally we’d include both the x and y arguments in the +specialisation, since we’re not specialising on either of them. But +that’s silly, since x is actually unused! So we might as well drop it +in the specialisation: + + $sf :: Int -> String + $sf y = show y ++ "!" + + {-# RULE "SPEC f @Int" forall x. f @Int x $dShow = $sf #-} + +This doesn’t save us much, since the arg would be removed later by +worker/wrapper, anyway, but it’s easy to do. Note, however, that we +only drop dead arguments if: + + 1. We don’t specialise on them. + 2. They come before an argument we do specialise on. + +Doing the latter would require eta-expanding the RULE, which could +make it match less often, so it’s not worth it. Doing the former could +be more useful --- it would stop us from generating pointless +specialisations --- but it’s more involved to implement and unclear if +it actually provides much benefit in practice. - { d1' = dx1; d2' = dx2 } +Note [Zap occ info in rule binders] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we generate a specialisation RULE, we need to drop occurrence +info on the binders. If we don’t, things go wrong when we specialise a +function like + + f :: forall a. () -> Show a => a -> String + f x y = show y ++ "!" + +since we’ll generate a RULE like + + RULE "SPEC f @Int" forall x [Occ=Dead]. + f @Int x $dShow = $sf + +and Core Lint complains, even though x only appears on the LHS (due to +Note [Drop dead args from specialisations]). -where d1', d2' are cloned versions of d1,d2, with the type substitution -applied. These auxiliary bindings just avoid duplication of dx1, dx2. +Why is that a Lint error? Because the arguments on the LHS of a rule +are syntactically expressions, not patterns, so Lint treats the +appearance of x as a use rather than a binding. Fortunately, the +solution is simple: we just make sure to zap the occ info before +using ids as wildcard binders in a rule. Note [Account for casts in binding] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1676,56 +1585,6 @@ type correctness issue.) But specialisation rules are strictly for What this means is that a SPEC rules from auto-specialisation in module M will be used in other modules only if M.hi has been read for some other reason, which is actually pretty likely. --} - -bindAuxiliaryDicts - :: SpecEnv - -> [DictId] -> [CoreExpr] -- Original dict bndrs, and the witnessing expressions - -> [DictId] -- A cloned dict-id for each dict arg - -> (SpecEnv, -- Substitute for all orig_dicts - [DictBind], -- Auxiliary dict bindings - [CoreExpr]) -- Witnessing expressions (all trivial) --- Bind any dictionary arguments to fresh names, to preserve sharing -bindAuxiliaryDicts env@(SE { se_subst = subst, se_interesting = interesting }) - orig_dict_ids call_ds inst_dict_ids - = (env', dx_binds, spec_dict_args) - where - (dx_binds, spec_dict_args) = go call_ds inst_dict_ids - env' = env { se_subst = subst `GHC.Core.Subst.extendSubstList` - (orig_dict_ids `zip` spec_dict_args) - `GHC.Core.Subst.extendInScopeList` dx_ids - , se_interesting = interesting `unionVarSet` interesting_dicts } - - dx_ids = [dx_id | (NonRec dx_id _, _) <- dx_binds] - interesting_dicts = mkVarSet [ dx_id | (NonRec dx_id dx, _) <- dx_binds - , interestingDict env dx ] - -- See Note [Make the new dictionaries interesting] - - go :: [CoreExpr] -> [CoreBndr] -> ([DictBind], [CoreExpr]) - go [] _ = ([], []) - go (dx:dxs) (dx_id:dx_ids) - | exprIsTrivial dx = (dx_binds, dx : args) - | otherwise = (mkDB (NonRec dx_id dx) : dx_binds, Var dx_id : args) - where - (dx_binds, args) = go dxs dx_ids - -- In the first case extend the substitution but not bindings; - -- in the latter extend the bindings but not the substitution. - -- For the former, note that we bind the *original* dict in the substitution, - -- overriding any d->dx_id binding put there by substBndrs - go _ _ = pprPanic "bindAuxiliaryDicts" (ppr orig_dict_ids $$ ppr call_ds $$ ppr inst_dict_ids) - -{- -Note [Make the new dictionaries interesting] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Important! We're going to substitute dx_id1 for d -and we want it to look "interesting", else we won't gather *any* -consequential calls. E.g. - f d = ...g d.... -If we specialise f for a call (f (dfun dNumInt)), we'll get -a consequent call (g d') with an auxiliary definition - d' = df dNumInt -We want that consequent call to look interesting - Note [From non-recursive to recursive] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2061,15 +1920,297 @@ a complete solution; ignoring specialisation for now, INLINABLE functions don't get properly strictness analysed, for example. But it works well for examples involving specialisation, which is the dominant use of INLINABLE. See #4874. +-} - -************************************************************************ +{- ********************************************************************* * * -\subsubsection{UsageDetails and suchlike} + SpecArg, and specHeader * * -************************************************************************ +********************************************************************* -} + +-- | An argument that we might want to specialise. +-- See Note [Specialising Calls] for the nitty gritty details. +data SpecArg + = + -- | Type arguments that should be specialised, due to appearing + -- free in the type of a 'SpecDict'. + SpecType Type + + -- | Type arguments that should remain polymorphic. + | UnspecType + + -- | Dictionaries that should be specialised. mkCallUDs ensures + -- that only "interesting" dictionary arguments get a SpecDict; + -- see Note [Interesting dictionary arguments] + | SpecDict DictExpr + + -- | Value arguments that should not be specialised. + | UnspecArg + +instance Outputable SpecArg where + ppr (SpecType t) = text "SpecType" <+> ppr t + ppr UnspecType = text "UnspecType" + ppr (SpecDict d) = text "SpecDict" <+> ppr d + ppr UnspecArg = text "UnspecArg" + +specArgFreeVars :: SpecArg -> VarSet +specArgFreeVars (SpecType ty) = tyCoVarsOfType ty +specArgFreeVars (SpecDict dx) = exprFreeVars dx +specArgFreeVars UnspecType = emptyVarSet +specArgFreeVars UnspecArg = emptyVarSet + +isSpecDict :: SpecArg -> Bool +isSpecDict (SpecDict {}) = True +isSpecDict _ = False + +-- | Given binders from an original function 'f', and the 'SpecArg's +-- corresponding to its usage, compute everything necessary to build +-- a specialisation. +-- +-- We will use the running example from Note [Specialising Calls]: +-- +-- f :: forall a b c. Int -> Eq a => Show b => c -> Blah +-- f @a @b @c i dEqA dShowA x = blah +-- +-- Suppose we decide to specialise it at the following pattern: +-- +-- [ SpecType T1, SpecType T2, UnspecType, UnspecArg +-- , SpecDict dEqT1, SpecDict ($dfShow dShowT2), UnspecArg ] +-- +-- We'd eventually like to build the RULE +-- +-- RULE "SPEC f @T1 @T2 _" +-- forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2). +-- f @T1 @T2 @c i d1 d2 = $sf @c i +-- +-- and the specialisation '$sf' +-- +-- $sf :: forall c. Int -> c -> Blah +-- $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah) +-- +-- where dShow1 is a floated binding created by bindAuxiliaryDict. +-- +-- The cases for 'specHeader' below are presented in the same order as this +-- running example. The result of 'specHeader' for this example is as follows: +-- +-- ( -- Returned arguments +-- env + [a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] +-- , [x] +-- +-- -- RULE helpers +-- , [c, i, d1, d2] +-- , [T1, T2, c, i, d1, d2] +-- +-- -- Specialised function helpers +-- , [c, i, x] +-- , [dShow1 = $dfShow dShowT2] +-- , [T1, T2, dEqT1, dShow1] +-- ) +specHeader + :: SpecEnv + -> [InBndr] -- The binders from the original function 'f' + -> [SpecArg] -- From the CallInfo + -> SpecM ( Bool -- True <=> some useful specialisation happened + -- Not the same as any (isSpecDict args) because + -- the args might be longer than bndrs + + -- Returned arguments + , SpecEnv -- Substitution to apply to the body of 'f' + , [OutBndr] -- Leftover binders from the original function 'f' + -- that don’t have a corresponding SpecArg + + -- RULE helpers + , [OutBndr] -- Binders for the RULE + , [CoreArg] -- Args for the LHS of the rule + + -- Specialised function helpers + , [OutBndr] -- Binders for $sf + , [DictBind] -- Auxiliary dictionary bindings + , [OutExpr] -- Specialised arguments for unfolding + ) + +-- We want to specialise on type 'T1', and so we must construct a substitution +-- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding +-- details. +specHeader env (bndr : bndrs) (SpecType t : args) + = do { let env' = extendTvSubstList env [(bndr, t)] + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , rule_bs + , Type t : rule_es + , bs' + , dx + , Type t : spec_args + ) + } + +-- Next we have a type that we don't want to specialise. We need to perform +-- a substitution on it (in case the type refers to 'a'). Additionally, we need +-- to produce a binder, LHS argument and RHS argument for the resulting rule, +-- /and/ a binder for the specialised body. +specHeader env (bndr : bndrs) (UnspecType : args) + = do { let (env', bndr') = substBndr env bndr + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , bndr' : rule_bs + , varToCoreExpr bndr' : rule_es + , bndr' : bs' + , dx + , varToCoreExpr bndr' : spec_args + ) + } + +-- Next we want to specialise the 'Eq a' dict away. We need to construct +-- a wildcard binder to match the dictionary (See Note [Specialising Calls] for +-- the nitty-gritty), as a LHS rule and unfolding details. +specHeader env (bndr : bndrs) (SpecDict d : args) + = do { bndr' <- newDictBndr env bndr -- See Note [Zap occ info in rule binders] + ; let (env', dx_bind, spec_dict) = bindAuxiliaryDict env bndr bndr' d + ; (_, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( True -- Ha! A useful specialisation! + , env'' + , leftover_bndrs + -- See Note [Evidence foralls] + , exprFreeIdsList (varToCoreExpr bndr') ++ rule_bs + , varToCoreExpr bndr' : rule_es + , bs' + , maybeToList dx_bind ++ dx + , spec_dict : spec_args + ) + } + +-- Finally, we have the unspecialised argument 'i'. We need to produce +-- a binder, LHS and RHS argument for the RULE, and a binder for the +-- specialised body. +-- +-- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is +-- why 'i' doesn't appear in our RULE above. But we have no guarantee that +-- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so +-- this case must be here. +specHeader env (bndr : bndrs) (UnspecArg : args) + = do { -- see Note [Zap occ info in rule binders] + let (env', bndr') = substBndr env (zapIdOccInfo bndr) + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , bndr' : rule_bs + , varToCoreExpr bndr' : rule_es + , if isDeadBinder bndr + then bs' -- see Note [Drop dead args from specialisations] + else bndr' : bs' + , dx + , varToCoreExpr bndr' : spec_args + ) + } + +-- If we run out of binders, stop immediately +-- See Note [Specialisation Must Preserve Sharing] +specHeader env [] _ = pure (False, env, [], [], [], [], [], []) + +-- Return all remaining binders from the original function. These have the +-- invariant that they should all correspond to unspecialised arguments, so +-- it's safe to stop processing at this point. +specHeader env bndrs [] + = pure (False, env', bndrs', [], [], [], [], []) + where + (env', bndrs') = substBndrs env bndrs + + +-- | Binds a dictionary argument to a fresh name, to preserve sharing +bindAuxiliaryDict + :: SpecEnv + -> InId -> OutId -> OutExpr -- Original dict binder, and the witnessing expression + -> ( SpecEnv -- Substitute for orig_dict_id + , Maybe DictBind -- Auxiliary dict binding, if any + , OutExpr) -- Witnessing expression (always trivial) +bindAuxiliaryDict env@(SE { se_subst = subst, se_interesting = interesting }) + orig_dict_id fresh_dict_id dict_expr + + -- If the dictionary argument is trivial, + -- don’t bother creating a new dict binding; just substitute + | Just dict_id <- getIdFromTrivialExpr_maybe dict_expr + = let env' = env { se_subst = Core.extendSubst subst orig_dict_id dict_expr + `Core.extendInScope` dict_id + -- See Note [Keep the old dictionaries interesting] + , se_interesting = interesting `extendVarSet` dict_id } + in (env', Nothing, dict_expr) + + | otherwise -- Non-trivial dictionary arg; make an auxiliary binding + = let dict_bind = mkDB (NonRec fresh_dict_id dict_expr) + env' = env { se_subst = Core.extendSubst subst orig_dict_id (Var fresh_dict_id) + `Core.extendInScope` fresh_dict_id + -- See Note [Make the new dictionaries interesting] + , se_interesting = interesting `extendVarSet` fresh_dict_id } + in (env', Just dict_bind, Var fresh_dict_id) + +{- +Note [Make the new dictionaries interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Important! We're going to substitute dx_id1 for d +and we want it to look "interesting", else we won't gather *any* +consequential calls. E.g. + f d = ...g d.... +If we specialise f for a call (f (dfun dNumInt)), we'll get +a consequent call (g d') with an auxiliary definition + d' = df dNumInt +We want that consequent call to look interesting + +Note [Keep the old dictionaries interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In bindAuxiliaryDict, we don’t bother creating a new dict binding if +the dict expression is trivial. For example, if we have + + f = \ @m1 (d1 :: Monad m1) -> ... + +and we specialize it at the pattern + + [SpecType IO, SpecArg $dMonadIO] + +it would be silly to create a new binding for $dMonadIO; it’s already +a binding! So we just extend the substitution directly: + + m1 :-> IO + d1 :-> $dMonadIO + +But this creates a new subtlety: the dict expression might be a dict +binding we floated out while specializing another function. For +example, we might have + + d2 = $p1Monad $dMonadIO -- floated out by bindAuxiliaryDict + $sg = h @IO d2 + h = \ @m2 (d2 :: Applicative m2) -> ... + +and end up specializing h at the following pattern: + + [SpecType IO, SpecArg d2] + +When we created the d2 binding in the first place, we locally marked +it as interesting while specializing g as described above by +Note [Make the new dictionaries interesting]. But when we go to +specialize h, it isn’t in the SpecEnv anymore, so we’ve lost the +knowledge that we should specialize on it. + +To fix this, we have to explicitly add d2 *back* to the interesting +set. That way, it will still be considered interesting while +specializing the body of h. See !2913. -} + +{- ********************************************************************* +* * + UsageDetails and suchlike +* * +********************************************************************* -} + data UsageDetails = MkUD { ud_binds :: !(Bag DictBind), @@ -2139,8 +2280,6 @@ data CallInfoSet = CIS Id (Bag CallInfo) data CallInfo = CI { ci_key :: [SpecArg] -- All arguments - , ci_arity :: Int -- The number of variables necessary to bind - -- all of the specialised arguments , ci_fvs :: VarSet -- Free vars of the ci_key -- call (including tyvars) -- [*not* include the main id itself, of course] @@ -2186,12 +2325,6 @@ callInfoFVs :: CallInfoSet -> VarSet callInfoFVs (CIS _ call_info) = foldr (\(CI { ci_fvs = fv }) vs -> unionVarSet fv vs) emptyVarSet call_info -computeArity :: [SpecArg] -> Int -computeArity = length . filter isValueArg . dropWhileEndLE isUnspecArg - -callSpecArity :: [TyCoBinder] -> Int -callSpecArity = length . filter (not . isNamedBinder) . dropWhileEndLE isVisibleBinder - getTheta :: [TyCoBinder] -> [PredType] getTheta = fmap tyBinderType . filter isInvisibleBinder . filter (not . isNamedBinder) @@ -2202,13 +2335,9 @@ singleCall id args = MkUD {ud_binds = emptyBag, ud_calls = unitDVarEnv id $ CIS id $ unitBag (CI { ci_key = args -- used to be tys - , ci_arity = computeArity args , ci_fvs = call_fvs }) } where - tys = getSpecTypes args - dicts = getSpecDicts args - call_fvs = exprsFreeVars dicts `unionVarSet` tys_fvs - tys_fvs = tyCoVarsOfTypes tys + call_fvs = foldr (unionVarSet . specArgFreeVars) emptyVarSet args -- The type args (tys) are guaranteed to be part of the dictionary -- types, because they are just the constrained types, -- and the dictionary is therefore sure to be bound @@ -2227,42 +2356,47 @@ mkCallUDs env f args res = mkCallUDs' env f args mkCallUDs' env f args - | not (want_calls_for f) -- Imported from elsewhere - || null theta -- Not overloaded - = emptyUDs - - | not (all type_determines_value theta) - || not (computeArity ci_key <= idArity f) - || not (length dicts == length theta) - || not (any (interestingDict env) dicts) -- Note [Interesting dictionary arguments] - -- See also Note [Specialisations already covered] + | not (want_calls_for f) -- Imported from elsewhere + || null ci_key -- No useful specialisation + -- See also Note [Specialisations already covered] = -- pprTrace "mkCallUDs: discarding" _trace_doc - emptyUDs -- Not overloaded, or no specialisation wanted + emptyUDs | otherwise = -- pprTrace "mkCallUDs: keeping" _trace_doc singleCall f ci_key where - _trace_doc = vcat [ppr f, ppr args, ppr (map (interestingDict env) dicts)] + _trace_doc = vcat [ppr f, ppr args, ppr ci_key] pis = fst $ splitPiTys $ idType f - theta = getTheta pis - constrained_tyvars = tyCoVarsOfTypes theta + constrained_tyvars = tyCoVarsOfTypes $ getTheta pis ci_key :: [SpecArg] - ci_key = fmap (\(t, a) -> - case t of - Named (binderVar -> tyVar) - | tyVar `elemVarSet` constrained_tyvars - -> case a of - Type ty -> SpecType ty - _ -> pprPanic "ci_key" $ ppr a - | otherwise - -> UnspecType - Anon InvisArg _ -> SpecDict a - Anon VisArg _ -> UnspecArg - ) $ zip pis args - - dicts = getSpecDicts ci_key + ci_key = dropWhileEndLE (not . isSpecDict) $ + zipWith mk_spec_arg args pis + -- Drop trailing args until we get to a SpecDict + -- In this way the RULE has as few args as possible, + -- which broadens its applicability, since rules only + -- fire when saturated + + mk_spec_arg :: CoreExpr -> TyCoBinder -> SpecArg + mk_spec_arg arg (Named bndr) + | binderVar bndr `elemVarSet` constrained_tyvars + = case arg of + Type ty -> SpecType ty + _ -> pprPanic "ci_key" $ ppr arg + | otherwise = UnspecType + + -- For "InvisArg", which are the type-class dictionaries, + -- we decide on a case by case basis if we want to specialise + -- on this argument; if so, SpecDict, if not UnspecArg + mk_spec_arg arg (Anon InvisArg pred) + | type_determines_value pred + , interestingDict env arg -- Note [Interesting dictionary arguments] + = SpecDict arg + | otherwise = UnspecArg + + mk_spec_arg _ (Anon VisArg _) + = UnspecArg want_calls_for f = isLocalId f || isJust (maybeUnfoldingTemplate (realIdUnfolding f)) -- For imported things, we gather call instances if @@ -2282,12 +2416,18 @@ mkCallUDs' env f args {- Note [Type determines value] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Only specialise if all overloading is on non-IP *class* params, -because these are the ones whose *type* determines their *value*. In -parrticular, with implicit params, the type args *don't* say what the -value of the implicit param is! See #7101 - -However, consider +Only specialise on non-IP *class* params, because these are the ones +whose *type* determines their *value*. In particular, with implicit +params, the type args *don't* say what the value of the implicit param +is! See #7101. + +So we treat implicit params just like ordinary arguments for the +purposes of specialisation. Note that we still want to specialise +functions with implicit params if they have *other* dicts which are +class params; see #17930. + +One apparent additional complexity involves type families. For +example, consider type family D (v::*->*) :: Constraint type instance D [] = () f :: D v => v Char -> Int @@ -2298,8 +2438,7 @@ and it's good to specialise f at this dictionary. So the question is: can an implicit parameter "hide inside" a type-family constraint like (D a). Well, no. We don't allow type instance D Maybe = ?x:Int -Hence the IrredPred case in type_determines_value. -See #7785. +Hence the IrredPred case in type_determines_value. See #7785. Note [Interesting dictionary arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2595,20 +2734,20 @@ mapAndCombineSM f (x:xs) = do (y, uds1) <- f x extendTvSubstList :: SpecEnv -> [(TyVar,Type)] -> SpecEnv extendTvSubstList env tv_binds - = env { se_subst = GHC.Core.Subst.extendTvSubstList (se_subst env) tv_binds } + = env { se_subst = Core.extendTvSubstList (se_subst env) tv_binds } substTy :: SpecEnv -> Type -> Type -substTy env ty = GHC.Core.Subst.substTy (se_subst env) ty +substTy env ty = Core.substTy (se_subst env) ty substCo :: SpecEnv -> Coercion -> Coercion -substCo env co = GHC.Core.Subst.substCo (se_subst env) co +substCo env co = Core.substCo (se_subst env) co substBndr :: SpecEnv -> CoreBndr -> (SpecEnv, CoreBndr) -substBndr env bs = case GHC.Core.Subst.substBndr (se_subst env) bs of +substBndr env bs = case Core.substBndr (se_subst env) bs of (subst', bs') -> (env { se_subst = subst' }, bs') substBndrs :: SpecEnv -> [CoreBndr] -> (SpecEnv, [CoreBndr]) -substBndrs env bs = case GHC.Core.Subst.substBndrs (se_subst env) bs of +substBndrs env bs = case Core.substBndrs (se_subst env) bs of (subst', bs') -> (env { se_subst = subst' }, bs') cloneBindSM :: SpecEnv -> CoreBind -> SpecM (SpecEnv, SpecEnv, CoreBind) @@ -2616,7 +2755,7 @@ cloneBindSM :: SpecEnv -> CoreBind -> SpecM (SpecEnv, SpecEnv, CoreBind) -- Return the substitution to use for RHSs, and the one to use for the body cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (NonRec bndr rhs) = do { us <- getUniqueSupplyM - ; let (subst', bndr') = GHC.Core.Subst.cloneIdBndr subst us bndr + ; let (subst', bndr') = Core.cloneIdBndr subst us bndr interesting' | interestingDict env rhs = interesting `extendVarSet` bndr' | otherwise = interesting @@ -2625,7 +2764,7 @@ cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (NonRec cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (Rec pairs) = do { us <- getUniqueSupplyM - ; let (subst', bndrs') = GHC.Core.Subst.cloneRecIdBndrs subst us (map fst pairs) + ; let (subst', bndrs') = Core.cloneRecIdBndrs subst us (map fst pairs) env' = env { se_subst = subst' , se_interesting = interesting `extendVarSetList` [ v | (v,r) <- pairs, interestingDict env r ] } @@ -2635,9 +2774,9 @@ newDictBndr :: SpecEnv -> CoreBndr -> SpecM CoreBndr -- Make up completely fresh binders for the dictionaries -- Their bindings are going to float outwards newDictBndr env b = do { uniq <- getUniqueM - ; let n = idName b - ty' = substTy env (idType b) - ; return (mkUserLocal (nameOccName n) uniq ty' (getSrcSpan n)) } + ; let n = idName b + ty' = substTy env (idType b) + ; return (mkUserLocal (nameOccName n) uniq ty' (getSrcSpan n)) } newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id -- Give the new Id a similar occurrence name to the old one ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -17,7 +17,7 @@ module GHC.Core.Subst ( deShadowBinds, substSpec, substRulesForImportedIds, substTy, substCo, substExpr, substExprSC, substBind, substBindSC, substUnfolding, substUnfoldingSC, - lookupIdSubst, lookupTCvSubst, substIdOcc, + lookupIdSubst, lookupTCvSubst, substIdType, substIdOcc, substTickish, substDVarSet, substIdInfo, -- ** Operations on substitutions @@ -756,4 +756,3 @@ analyser, so it's possible that the worker is not even in scope any more. In all all these cases we simply drop the special case, returning to InlVanilla. The WARN is just so I can see if it happens a lot. -} - ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -172,15 +172,16 @@ mkInlinableUnfolding dflags expr where expr' = simpleOptExpr dflags expr -specUnfolding :: DynFlags -> [Var] -> (CoreExpr -> CoreExpr) -> Arity +specUnfolding :: DynFlags -> Id -> [Var] -> (CoreExpr -> CoreExpr) -> Arity -> Unfolding -> Unfolding -- See Note [Specialising unfoldings] -- specUnfolding spec_bndrs spec_app arity_decrease unf -- = \spec_bndrs. spec_app( unf ) -- -specUnfolding dflags spec_bndrs spec_app arity_decrease +specUnfolding dflags fn spec_bndrs spec_app arity_decrease df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args }) - = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs, ppr df ) + = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs + , ppr df $$ ppr spec_bndrs $$ ppr (spec_app (Var fn)) $$ ppr arity_decrease ) mkDFunUnfolding spec_bndrs con (map spec_arg args) -- There is a hard-to-check assumption here that the spec_app has -- enough applications to exactly saturate the old_bndrs @@ -194,7 +195,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr -specUnfolding dflags spec_bndrs spec_app arity_decrease +specUnfolding dflags _ spec_bndrs spec_app arity_decrease (CoreUnfolding { uf_src = src, uf_tmpl = tmpl , uf_is_top = top_lvl , uf_guidance = old_guidance }) @@ -211,7 +212,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease in mkCoreUnfolding src top_lvl new_tmpl guidance -specUnfolding _ _ _ _ _ = noUnfolding +specUnfolding _ _ _ _ _ _ = noUnfolding {- Note [Specialising unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -701,7 +701,7 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl)) { this_mod <- getModule ; let fn_unf = realIdUnfolding poly_id - spec_unf = specUnfolding dflags spec_bndrs core_app arity_decrease fn_unf + spec_unf = specUnfolding dflags poly_id spec_bndrs core_app arity_decrease fn_unf spec_id = mkLocalId spec_name spec_ty `setInlinePragma` inl_prag `setIdUnfolding` spec_unf ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -92,6 +92,12 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) @@ -117,18 +123,19 @@ Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -2,6 +2,11 @@ TOP=../../.. include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk +T17966: + $(RM) -f T17966.o T17966.hi + - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-spec T17966.hs 2> /dev/null | grep 'SPEC' + # Expecting a SPEC rule for $cm + T17409: $(RM) -f T17409.o T17409.hi - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -dverbose-core2core -dsuppress-uniques T17409.hs 2> /dev/null | grep '\' ===================================== testsuite/tests/simplCore/should_compile/T17810.hs ===================================== @@ -0,0 +1,7 @@ +module T17801 where + +import Control.Monad.Except +import T17810a + +f :: ExceptT e (TCMT IO) () +f = liftReduce ===================================== testsuite/tests/simplCore/should_compile/T17810a.hs ===================================== @@ -0,0 +1,27 @@ +module T17810a where + +import Control.Monad.Except + +class Monad m => ReadTCState m where + locallyTCState :: m () + liftReduce :: m () + +instance ReadTCState m => ReadTCState (ExceptT err m) where + locallyTCState = undefined + liftReduce = lift liftReduce + +instance MonadIO m => ReadTCState (TCMT m) where + locallyTCState = (undefined <$> liftReduce) <* TCM (\_ -> return ()) + liftReduce = undefined + +newtype TCMT m a = TCM { unTCM :: () -> m a } + +instance MonadIO m => Functor (TCMT m) where + fmap f (TCM m) = TCM $ \r -> liftM f (m r ) + +instance MonadIO m => Applicative (TCMT m) where + pure x = TCM (\_ -> return x) + (<*>) (TCM mf) (TCM m) = TCM $ \r -> ap (mf r) (m r) + +instance MonadIO m => Monad (TCMT m) where + (>>=) (TCM m) k = TCM $ \r -> m r >>= \x -> unTCM (k x) r ===================================== testsuite/tests/simplCore/should_compile/T17930.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE ImplicitParams #-} +module T17930 where + +foo :: (?b :: Bool, Show a) => a -> String +foo x | ?b = show x ++ "!" + | otherwise = show x ++ "." +{-# INLINABLE[0] foo #-} + +str :: String +str = let ?b = True in foo "Hello" ===================================== testsuite/tests/simplCore/should_compile/T17930.stderr ===================================== @@ -0,0 +1,2 @@ +$sfoo :: (?b::Bool) => [Char] -> [Char] +$sfoo ===================================== testsuite/tests/simplCore/should_compile/T17966.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +-- The issue here is whether $cm gets a specialiation +-- See #17966 + +module T17966 where + +class C a b where + m :: Show c => a -> b -> c -> String + +instance Show b => C Bool b where + m a b c = show a ++ show b ++ show c + {-# INLINABLE [0] m #-} + +f :: (C a b, Show c) => a -> b -> c -> String +f a b c = m a b c ++ "!" +{-# INLINABLE [0] f #-} + +x :: String +x = f True () (Just 42) ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -0,0 +1,4 @@ + RULES: "SPEC $cm @()" [0] + RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] +"SPEC/T17966 $fShowMaybe_$cshowList @Integer" +"SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -319,3 +319,10 @@ test('T17787', [ grep_errmsg(r'foo') ], compile, ['-ddump-simpl -dsuppress-uniq test('T17901', normal, makefile_test, ['T17901']) +test('T17930', [ grep_errmsg(r'^\$sfoo') ], compile, ['-O -ddump-spec -dsuppress-uniques -dsuppress-idinfo']) +test('spec004', [ grep_errmsg(r'\$sfoo') ], compile, ['-O -ddump-spec -dsuppress-uniques']) +test('T17966', + normal, + makefile_test, ['T17966']) +# NB: T17810: -fspecialise-aggressively +test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) ===================================== testsuite/tests/simplCore/should_compile/spec004.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE RankNTypes #-} + +-- Dead arguments should be dropped in specialisations. See !2913. + +module ShouldCompile where + +foo :: () -> Show a => a -> String +foo _x y = show y ++ "!" +{-# NOINLINE[0] foo #-} + +bar :: String +bar = foo () (42 :: Int) ===================================== testsuite/tests/simplCore/should_compile/spec004.stderr ===================================== @@ -0,0 +1,84 @@ + +==================== Specialise ==================== +Result size of Specialise + = {terms: 53, types: 46, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 14, types: 12, coercions: 0, joins: 0/0} +$sfoo [InlPrag=NOINLINE[0]] :: Int -> [Char] +[LclId] +$sfoo + = \ (y :: Int) -> + GHC.Base.build + @Char + (\ (@b) (c [OS=OneShot] :: Char -> b -> b) (n [OS=OneShot] :: b) -> + GHC.Base.foldr + @Char + @b + c + (GHC.CString.unpackFoldrCString# @b "!"# c n) + (show @Int GHC.Show.$fShowInt y)) + +-- RHS size: {terms: 17, types: 17, coercions: 0, joins: 0/0} +foo [InlPrag=NOINLINE[0]] :: forall a. () -> Show a => a -> String +[LclIdX, + Arity=3, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 30 0] 150 40}, + RULES: "SPEC foo @Int" [0] + forall (dk :: ()) ($dShow :: Show Int). foo @Int dk $dShow = $sfoo] +foo + = \ (@a) _ [Occ=Dead] ($dShow :: Show a) (y :: a) -> + GHC.Base.build + @Char + (\ (@b) (c [OS=OneShot] :: Char -> b -> b) (n [OS=OneShot] :: b) -> + GHC.Base.foldr + @Char + @b + c + (GHC.CString.unpackFoldrCString# @b "!"# c n) + (show @a $dShow y)) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 50 0}] +$trModule = "ShouldCompile"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +ShouldCompile.$trModule :: GHC.Types.Module +[LclIdX, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +ShouldCompile.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +bar :: String +[LclIdX, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 0}] +bar = foo @Int GHC.Tuple.() GHC.Show.$fShowInt (GHC.Types.I# 42#) + + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a8b2ae4385fff0ff6255744e2b3a0ba4f86b7b04 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a8b2ae4385fff0ff6255744e2b3a0ba4f86b7b04 You're receiving 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 1 09:22:37 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 01 Apr 2020 05:22:37 -0400 Subject: [Git][ghc/ghc][wip/T17966] 10 commits: Require GHC 8.8 as the minimum compiler for bootstrapping Message-ID: <5e845d5d2cf5_616776d1c74213866b@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17966 at Glasgow Haskell Compiler / GHC Commits: 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7052d7c7 by Simon Peyton Jones at 2020-04-01T10:22:10+01:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Types/Unique/Supply.hs - compiler/main/SysTools/Process.hs - compiler/main/SysTools/Terminal.hs - compiler/typecheck/TcDeriv.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcRnTypes.hs - compiler/typecheck/TcSMonad.hs - compiler/typecheck/TcSplice.hs - compiler/utils/Binary.hs - compiler/utils/IOEnv.hs - configure.ac - distrib/configure.ac.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a8b2ae4385fff0ff6255744e2b3a0ba4f86b7b04...7052d7c7ce3418db9e66ad6ff31e80b2a2c724bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a8b2ae4385fff0ff6255744e2b3a0ba4f86b7b04...7052d7c7ce3418db9e66ad6ff31e80b2a2c724bb You're receiving 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 1 09:25:58 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 01 Apr 2020 05:25:58 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_datacon] 265 commits: Separate CPR analysis from the Demand analyser Message-ID: <5e845e2661a32_616768300442142294@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_datacon at Glasgow Haskell Compiler / GHC Commits: 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - c0cd3925 by Andreas Klebinger at 2020-04-01T11:25:41+02:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - 30 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/win32-init.sh - HACKING.md - aclocal.m4 - boot - compiler/main/GHC.hs → compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f48c62209b65013e2bfb5de1dbdbef4977718b79...c0cd3925633d941884ea42e6f2f8cb60b5c57ffc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f48c62209b65013e2bfb5de1dbdbef4977718b79...c0cd3925633d941884ea42e6f2f8cb60b5c57ffc You're receiving 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 1 10:31:46 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 01 Apr 2020 06:31:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/osa1/std_string_thunks Message-ID: <5e846d9211089_61675cefcac2156376@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed new branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/osa1/std_string_thunks You're receiving 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 1 10:43:31 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 01 Apr 2020 06:43:31 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Bugs in closure def Message-ID: <5e8470539ceb8_6167120434ec2159152@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 2899512a by Ömer Sinan Ağacan at 2020-04-01T13:43:24+03:00 Bugs in closure def - - - - - 1 changed file: - rts/StgStdThunks.cmm Changes: ===================================== rts/StgStdThunks.cmm ===================================== @@ -13,6 +13,8 @@ #include "Cmm.h" #include "Updates.h" +import CLOSURE base_GHCziCStringziunpackCStringzh_info; + /* ----------------------------------------------------------------------------- The code for a thunk that simply extracts a field from a single-constructor datatype depends only on the offset of the field @@ -303,6 +305,6 @@ INFO_TABLE(stg_MK_STRING, 0, 0, FUN_STATIC, "stg_MK_STRING", "stg_MK_STRING") Sp_adj(-2); Sp(1) = node; Sp(0) = stg_bh_upd_frame_info; - jump GHCziCStringziunpackCStringzhzuinfo(node); + jump base_GHCziCStringziunpackCStringzh_info(StgThunk_payload(node,0)); } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2899512ac1489ae8208dbe44e01762bb852f3e49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2899512ac1489ae8208dbe44e01762bb852f3e49 You're receiving 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 1 10:46:11 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 06:46:11 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Add ConOrDiv to Divergence and see where it gets us Message-ID: <5e8470f33fe_6167120434ec21631ed@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 94ec6e6d by Sebastian Graf at 2020-04-01T12:39:42+02:00 Add ConOrDiv to Divergence and see where it gets us - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94ec6e6d4f48d87199b88f245e30e5e86c411347 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94ec6e6d4f48d87199b88f245e30e5e86c411347 You're receiving 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 1 15:23:18 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 11:23:18 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/primop-traits Message-ID: <5e84b1e64a837_616776d1c742265542@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/primop-traits at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/primop-traits You're receiving 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 1 15:24:21 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 11:24:21 -0400 Subject: [Git][ghc/ghc][wip/primop-traits] Clear up PrimOp effect semantics Message-ID: <5e84b2259200e_616768300442265785@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/primop-traits at Glasgow Haskell Compiler / GHC Commits: bbd20a71 by Sebastian Graf at 2020-04-01T17:23:55+02:00 Clear up PrimOp effect semantics Previously we classified PrimOps with two boolean flags, `can_fail` and `has_side_effects`. Although there is quite a slew of documentation surrounding them, see `Note [PrimOp can_fail and has_side_effects]` and `Note [Transformations affected by can_fail and has_side_effects]`, I found it quite hard to understand and also was confused of conservative misclassifications for some read-only primops like `readMutVar#` (which is marked as `has_side_effect`, although it actually shouldn't per semantics of `has_side_effect`, see #3207), but not for others (`indexIntArr#`, which is just `can_fail`). This patch defines a total order of 5 different `PrimOpEffect`s: - `NoEffect`: A pure primop - `ReadEffect`: Ideally, `readMutVar#` should be this kind of effect, but due to #3207 it's a `WriteEffect` and this effect will probably be unused (TODO: Implement and comment on this). - `ThrowsImprecise`: Possibly throws an imprecise exception (and may perform read effects) - `WriteEffect`: May write to a mutable ref cell, array or the world (or read from them or throw an imprecise exception) - `ThrowsPrecise`: May throw a precise exception, or do any of the aforementioned effects. Each effect is strictly "stronger" than its predecessor in this list wrt. to program transformation that are sound to apply to it. For example, we may speculatively execute read effects (as long as their data dependencies such as the state token are satisfied), but we may not speculate division (for fear of imprecise division-by-zero errors). Which `PrimOpEffect` inhibits which transformation, including examples, is spelled out in the rewritten `Note [Transformations affected by PrimOpEffect]`. Fixes #17900. - - - - - 1 changed file: - compiler/prelude/PrimOp.hs Changes: ===================================== compiler/prelude/PrimOp.hs ===================================== @@ -299,132 +299,180 @@ perform a heap check or they block. primOpOutOfLine :: PrimOp -> Bool #include "primop-out-of-line.hs-incl" + {- ************************************************************************ * * Failure and side effects * * ************************************************************************ +-} -Note [Checking versus non-checking primops] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - In GHC primops break down into two classes: - - a. Checking primops behave, for instance, like division. In this - case the primop may throw an exception (e.g. division-by-zero) - and is consequently is marked with the can_fail flag described below. - The ability to fail comes at the expense of precluding some optimizations. - - b. Non-checking primops behavior, for instance, like addition. While - addition can overflow it does not produce an exception. So can_fail is - set to False, and we get more optimisation opportunities. But we must - never throw an exception, so we cannot rewrite to a call to error. - - It is important that a non-checking primop never be transformed in a way that - would cause it to bottom. Doing so would violate Core's let/app invariant - (see Note [Core let/app invariant] in GHC.Core) which is critical to - the simplifier's ability to float without fear of changing program meaning. - - -Note [PrimOp can_fail and has_side_effects] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Both can_fail and has_side_effects mean that the primop has -some effect that is not captured entirely by its result value. - ----------- has_side_effects --------------------- -A primop "has_side_effects" if it has some *write* effect, visible -elsewhere - - writing to the world (I/O) - - writing to a mutable data structure (writeIORef) - - throwing a synchronous Haskell exception - -Often such primops have a type like - State -> input -> (State, output) -so the state token guarantees ordering. In general we rely *only* on -data dependencies of the state token to enforce write-effect ordering - - * NB1: if you inline unsafePerformIO, you may end up with - side-effecting ops whose 'state' output is discarded. - And programmers may do that by hand; see #9390. - That is why we (conservatively) do not discard write-effecting - primops even if both their state and result is discarded. - - * NB2: We consider primops, such as raiseIO#, that can raise a - (Haskell) synchronous exception to "have_side_effects" but not - "can_fail". We must be careful about not discarding such things; - see the paper "A semantics for imprecise exceptions". - - * NB3: *Read* effects (like reading an IORef) don't count here, - because it doesn't matter if we don't do them, or do them more than - once. *Sequencing* is maintained by the data dependency of the state - token. - ----------- can_fail ---------------------------- -A primop "can_fail" if it can fail with an *unchecked* exception on -some elements of its input domain. Main examples: - division (fails on zero denominator) - array indexing (fails if the index is out of bounds) - -An "unchecked exception" is one that is an outright error, (not -turned into a Haskell exception,) such as seg-fault or -divide-by-zero error. Such can_fail primops are ALWAYS surrounded -with a test that checks for the bad cases, but we need to be -very careful about code motion that might move it out of -the scope of the test. - -Note [Transformations affected by can_fail and has_side_effects] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The can_fail and has_side_effects properties have the following effect -on program transformations. Summary table is followed by details. - - can_fail has_side_effects -Discard YES NO -Float in YES YES -Float out NO NO -Duplicate YES NO +-- | A classification of primops by triggered side effects. +-- See Note [Classification by PrimOpEffect]. +-- The `Ord` instance is significant. A "stronger" effect means less +-- transformations are sound to apply to them. +data PrimOpEffect + = NoEffect + | ReadEffect + | ThrowsImprecise + | WriteEffect + | ThrowsPrecise + deriving (Eq, Ord) + +-- | Can we discard a call to the primop, i.e. @case a `op` b of _ -> rhs@? +-- This is a question that i.e. the Simplifier asks before dropping the @case at . +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDiscardablePrimOpEffect :: PrimOpEffect -> Bool +isDiscardablePrimOpEffect eff = eff <= ThrowsImprecise + +-- | Can we duplicate a call to the primop? +-- This is a question that i.e. the Simplifier asks when inlining definitions +-- involving primops with multiple syntactic occurrences. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDupablePrimOpEffect :: PrimOpEffect -> Bool +-- isDupablePrimOpEffect eff = True -- #3207, see the Note +isDupablePrimOpEffect eff = eff <= ThrowsImprecise + +-- | Can we perform other actions first before entering the primop? +-- This is the question that i.e. @FloatIn@ asks. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDeferrablePrimOpEffect :: PrimOpEffect -> Bool +isDeferrablePrimOpEffect eff = eff <= WriteEffect + +-- | Can we speculatively execute this primop, before performing other actions +-- that should come first according to evaluation strategy? +-- This is the question that i.e. @FloatOut@ (of a @case@) asks. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isSpeculatablePrimOpEffect :: PrimOpEffect -> Bool +isSpeculatablePrimOpEffect eff = eff <= ReadEffect + +{- Note [Classification by PrimOpEffect] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Some primops have effects that are not captured entirely by their result value. +We distinguish these cases: + + * NoEffect: Pure primop, like `plusInt#`. + * ReadEffect: A read-only primop, like `readMutVar#`, if it wasn't for #3207. + * ThrowsImprecise: Possibly throws an *imprecise* exception, like + division-by-zero or a segfault arising from an out of bounds array access. + An imprecise exception is an outright error and transformations may play + fast and loose by turning one imprecise exception into another, or bottom. + See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + * WriteEffect: A write side-effect, either writing to the RealWorld (IO) or + to a mutable variable (`writeMutVar#`). + * ThrowsPrecise: Possibly throws a *precise* exception. `raiseIO#` is the + only primop that does that. + See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + +Why is this classification necessary? Because the kind of effect a primop +performs influences the transformations we are allowed to apply to it. +For example let binding a division-by-zero (which `ThrowsImprecise`) might +violate Core's let/app invariant (see Note [Core let/app invariant] in +GHC.Core) which is critical to the simplifier's ability to float without fear +of changing program meaning. + +See Note [Transformations affected by PrimOpEffect]. + +Note [Transformations affected by PrimOpEffect] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The PrimOpEffect of a primop affects applicability of program transformations +in the following way. +Summary table is followed by details. + + | NoEff. | ReadEff. | ThrowsImp. | WriteEff. | ThrowsPrec. | +Discard | YES | YES | YES | NO | NO | +Dupe | YES | NO^[1] | NO^[1] | NO | NO | +Defer | YES | YES | YES | YES | NO | +Speculate | YES | YES | NO | NO | NO | + +[1] This is only due to #3207, and should only apply to read effects that can +be interleaved with write effects (e.g. mutable arrays as opposed to immutable +ones). More details below. + +Note how there is a total order on effects in terms of which program +tranformations they inhibit. A "stronger" effect means less transformations +are sound to apply to it. NoEffect means any tranformation is sound; +ThrowsPrecise means none of the following is. +Whether or not a primop is cheap to evaluate is an orthogonal concern. * Discarding. case (a `op` b) of _ -> rhs ===> rhs - You should not discard a has_side_effects primop; e.g. + You should not discard a WriteEffect or ThrowsPrecise primop; e.g. case (writeIntArray# a i v s of (# _, _ #) -> True - Arguably you should be able to discard this, since the - returned stat token is not used, but that relies on NEVER - inlining unsafePerformIO, and programmers sometimes write - this kind of stuff by hand (#9390). So we (conservatively) - never discard a has_side_effects primop. - - However, it's fine to discard a can_fail primop. For example + Arguably you should be able to discard this, since the returned state token + is not used, but that relies on NEVER inlining unsafePerformIO, and + programmers sometimes write this kind of stuff by hand (#9390). So we + (conservatively) never discard such a primop. + The situation with ThrowsPrecise primops such as raiseIO# is even more + restrictive: We may never discard a side effect throwing a precise exception. + + However, it's fine to discard a ThrowsImprecise primop. For example case (indexIntArray# a i) of _ -> True - We can discard indexIntArray#; it has can_fail, but not - has_side_effects; see #5658 which was all about this. - Notice that indexIntArray# is (in a more general handling of - effects) read effect, but we don't care about that here, and - treat read effects as *not* has_side_effects. - - Similarly (a `/#` b) can be discarded. It can seg-fault or - cause a hardware exception, but not a synchronous Haskell - exception. - - - - Synchronous Haskell exceptions, e.g. from raiseIO#, are treated - as has_side_effects and hence are not discarded. + We can discard indexIntArray#; it might throw an imprecise segmentation + fault, but no precise exception, so we are OK with not observing it. + See #5658 which was all about this. + Similarly (a `/#` b) can be discarded. It can seg-fault or cause a hardware + exception, but not a precise Haskell exception. + It's obviously fine to discard a ReadEffect if its result aren't used. + +* Duplication. Example: The Simplifier inlines a (multi occ) binding. + You cannot duplicate any effectful primop participating in state token + threading. Not even what is actually a read-only effect like `readMutVar#`, + see #3207. + You might wonder how that can be problematic, but just look at + Control.Monad.ST.Lazy.Imp.strictToLazy! We get something like this + p = case readMutVar# s v of + (# s', r #) -> (S# s', r) + s' = case p of (s', r) -> s' + r = case p of (s', r) -> r -* Float in. You can float a can_fail or has_side_effects primop - *inwards*, but not inside a lambda (see Duplication below). + (All these bindings are boxed.) If we inline p at its two call + sites, we get a catastrophe: because the read is performed once when + s' is demanded, and once when 'r' is demanded, which may be much + later. Utterly wrong. #3207 is real example of this happening. -* Float out. You must not float a can_fail primop *outwards* lest - you escape the dynamic scope of the test. Example: + If it wasn't for working around state token threading + (see https://gitlab.haskell.org/ghc/ghc/issues/3207#note_257470 for other + approaches), then duplication wouldn't be an issue at all, soundness-wise. + But for the time being, we mark primops that participate in state token + threading such as `readMutVar#` (a ReadEffect at heart) and `readArray#` + (ThrowsImprecise) as WriteEffect and say that we may not duplicate + WriteEffect. + +* Deferring. Example: FloatIn, here inside a single-alt case: + case (a `op` b) of (# s, x #) -> case e of p -> rhs + ==> + case e of p -> case (a `op` b) of (# s, x #) -> rhs + Note that e might diverge (or throw an imprecise exception) and thus the + side-effect we would observe by evaluating op might not happen if we defer it + after e. + + That is a problem if op ThrowsPrecise: If e diverges, the user can catch + the precise exception /before/ FloatIn, but not afterwards. Hence we may not + float in a ThrowsPrecise primop like raiseIO#. + + But since e can never throw an imprecise exception, there is no + non-imprecise-exceptional control flow in which it is possible to observe + that a WriteEffect (and anything "weaker") didn't happen. So it's OK to + defer (every weaker than or equal to) write effects. So you can float a + WriteEffect *inwards*, but not inside a lambda (see Duplication below [SG: It + isn't obvious to me how that explains why we shouldn't float inside a lambda + at all]). + +* Speculating. Example: Float out. + You must not float a ThrowsImprecise primop *outwards* lest you escape the + dynamic scope of the test. Example: case d ># 0# of True -> case x /# d of r -> r +# 1 False -> 0 - Here we must not float the case outwards to give + Here we must not float the division outwards to give case x/# d of r -> case d ># 0# of True -> r +# 1 False -> 0 + Now the potential division by zero will be performed in both branches. - Nor can you float out a has_side_effects primop. For example: + Similarly you can't float out a (stronger) WriteEffect primop. For example: if blah then case writeMutVar# v True s0 of (# s1 #) -> s1 else s0 Notice that s0 is mentioned in both branches of the 'if', but @@ -435,22 +483,9 @@ Duplicate YES NO the writeMutVar will be performed in both branches, which is utterly wrong. -* Duplication. You cannot duplicate a has_side_effect primop. You - might wonder how this can occur given the state token threading, but - just look at Control.Monad.ST.Lazy.Imp.strictToLazy! We get - something like this - p = case readMutVar# s v of - (# s', r #) -> (S# s', r) - s' = case p of (s', r) -> s' - r = case p of (s', r) -> r - - (All these bindings are boxed.) If we inline p at its two call - sites, we get a catastrophe: because the read is performed once when - s' is demanded, and once when 'r' is demanded, which may be much - later. Utterly wrong. #3207 is real example of this happening. - - However, it's fine to duplicate a can_fail primop. That is really - the only difference between can_fail and has_side_effects. + It's OK to speculate read effects such as readMutVar#, though, because + they can't move before a i.e. write effect purely by data dependency on the + state token. Note [Implementation: how can_fail/has_side_effects affect transformations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bbd20a71a1f27bc03cb8e59acf5ccb6516a2de37 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bbd20a71a1f27bc03cb8e59acf5ccb6516a2de37 You're receiving 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 1 15:54:19 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 01 Apr 2020 11:54:19 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] 273 commits: Document GMP build [skip ci] Message-ID: <5e84b92beec7e_61675cefcac22688d7@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 774d1f47 by Andreas Klebinger at 2020-04-01T17:53:52+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. We optimize `elem` now in more ways than before. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks. These ultimately simply to a single case expression. It will also turn into a fold for dynamic lists when list fusion applies. This logic however does not work on string literals. For this reason I added a rule to do the transformation into a case explicitly via a built in rule. It will fire for any short string literals. (<=32 Bytes). Longer calls to elem on string literals are rewritten to calls to elem variants specialized to string literals. This means we will rewrite: * c `elem` (unpackCString "Foo"#) => elemCString# c' "Foo"# * c `elem` (unpackCStringUtf8 "Bär"#) => elemCStringUtf8# c' "Bär"# This means all calls to elem on string literals, as well as many on other statically known lists should now be allocation free. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors. A version of `elem` operating on known string literals was added: * elemCString# :: Char# -> Addr# -> Bool * elemCStringUtf8# :: Char# -> Addr# -> Bool - - - - - 30 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/win32-init.sh - HACKING.md - aclocal.m4 - boot - compiler/main/GHC.hs → compiler/GHC.hs - compiler/ghci/ByteCodeAsm.hs → compiler/GHC/ByteCode/Asm.hs - compiler/ghci/ByteCodeItbls.hs → compiler/GHC/ByteCode/InfoTable.hs - compiler/ghci/ByteCodeInstr.hs → compiler/GHC/ByteCode/Instr.hs - compiler/ghci/ByteCodeLink.hs → compiler/GHC/ByteCode/Linker.hs - compiler/ghci/ByteCodeTypes.hs → compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf3313927aa8801d9aab740b10bf26778626dcd7...774d1f47016e662eaf0c7ac4189f73439f3beab3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf3313927aa8801d9aab740b10bf26778626dcd7...774d1f47016e662eaf0c7ac4189f73439f3beab3 You're receiving 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 1 17:17:14 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 13:17:14 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] DmdAnal: Reflect precise exceptions in demand types Message-ID: <5e84cc9ad1236_61673f8198ee100c22871db@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: db0d66bd by Sebastian Graf at 2020-04-01T17:29:28+02:00 DmdAnal: Reflect precise exceptions in demand types In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, for example in the following program (a play on #13380, `T13380b`): ```hs m :: IO () m = error "pattern error or whatever imprecise exception" {-# NOINLINE m #-} f :: Int -> Int -> IO Int -- à la #13380 f x y | x>0 = m >> return 0 | y>0 = return 1 | otherwise = return 2 {-# NOINLINE f #-} ``` Currently, we fail to infer that `m` always diverges without throwing a precise exception and hence that `f` is strict in `y`. Quite The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) Apart from being possibly unsound, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`, it is also imprecise, for example for the following program (`T13380b`): - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/db0d66bd4522ac04a24e5754faaedf43e1b1c540 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/db0d66bd4522ac04a24e5754faaedf43e1b1c540 You're receiving 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 1 18:09:09 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 14:09:09 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] DmdAnal: Reflect precise exceptions in demand types Message-ID: <5e84d8c587a68_616776d1c74230027f@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: f5344aa5 by Sebastian Graf at 2020-04-01T20:07:42+02:00 DmdAnal: Reflect precise exceptions in demand types In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5344aa5534a33125ddf6a18499701c948745898 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5344aa5534a33125ddf6a18499701c948745898 You're receiving 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 1 18:14:57 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 14:14:57 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] DmdAnal: Reflect precise exceptions in demand types Message-ID: <5e84da2194bcd_61675cefcac2302019@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: d9d8b11b by Sebastian Graf at 2020-04-01T20:09:11+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d9d8b11baed5617977cedc33e28d014e8e8d68c8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d9d8b11baed5617977cedc33e28d014e8e8d68c8 You're receiving 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 1 18:16:04 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 01 Apr 2020 14:16:04 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] DmdAnal: Reflect precise exceptions in demand types Message-ID: <5e84da64a1fce_616766534602302218@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: c2a0aabe by Sebastian Graf at 2020-04-01T20:15:55+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2a0aabe2e57ccc74bbd0801635b14f7d055e8f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2a0aabe2e57ccc74bbd0801635b14f7d055e8f8 You're receiving 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 1 19:03:33 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 15:03:33 -0400 Subject: [Git][ghc/ghc][master] PmCheck: Adjust recursion depth for inhabitation test Message-ID: <5e84e585a9ff7_616776d1c742311653@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 5 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - + testsuite/tests/pmcheck/should_compile/T17977.hs - + testsuite/tests/pmcheck/should_compile/T17977b.hs - + testsuite/tests/pmcheck/should_compile/T17977b.stderr - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -1319,10 +1319,11 @@ checkAllNonVoid :: RecTcChecker -> Delta -> [Type] -> DsM Bool checkAllNonVoid rec_ts amb_cs strict_arg_tys = do let definitely_inhabited = definitelyInhabitedType (delta_ty_st amb_cs) tys_to_check <- filterOutM definitely_inhabited strict_arg_tys + -- See Note [Fuel for the inhabitation test] let rec_max_bound | tys_to_check `lengthExceeds` 1 = 1 | otherwise - = defaultRecTcMaxBound + = 3 rec_ts' = setRecTcMaxBound rec_max_bound rec_ts allM (nonVoid rec_ts' amb_cs) tys_to_check @@ -1342,6 +1343,7 @@ nonVoid rec_ts amb_cs strict_arg_ty = do mb_cands <- inhabitationCandidates amb_cs strict_arg_ty case mb_cands of Right (tc, _, cands) + -- See Note [Fuel for the inhabitation test] | Just rec_ts' <- checkRecTc rec_ts tc -> anyM (cand_is_inhabitable rec_ts' amb_cs) cands -- A strict argument type is inhabitable by a terminating value if @@ -1390,7 +1392,7 @@ definitelyInhabitedType ty_st ty = do null (dataConImplBangs con) -- (2) {- Note [Strict argument type constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the ConVar case of clause processing, each conlike K traditionally generates two different forms of constraints: @@ -1420,6 +1422,7 @@ say, `K2 undefined` or `K2 (let x = x in x)`.) Since neither the term nor type constraints mentioned above take strict argument types into account, we make use of the `nonVoid` function to determine whether a strict type is inhabitable by a terminating value or not. +We call this the "inhabitation test". `nonVoid ty` returns True when either: 1. `ty` has at least one InhabitationCandidate for which both its term and type @@ -1445,15 +1448,20 @@ determine whether a strict type is inhabitable by a terminating value or not. `nonVoid MyVoid` returns False. The InhabitationCandidate for the MkMyVoid constructor contains Void as a strict argument type, and since `nonVoid Void` returns False, that InhabitationCandidate is discarded, leaving no others. +* Whether or not a type is inhabited is undecidable in general. + See Note [Fuel for the inhabitation test]. +* For some types, inhabitation is evident immediately and we don't need to + perform expensive tests. See Note [Types that are definitely inhabitable]. -* Performance considerations +Note [Fuel for the inhabitation test] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Whether or not a type is inhabited is undecidable in general. As a result, we +can run into infinite loops in `nonVoid`. Therefore, we adopt a fuel-based +approach to prevent that. -We must be careful when recursively calling `nonVoid` on the strict argument -types of an InhabitationCandidate, because doing so naïvely can cause GHC to -fall into an infinite loop. Consider the following example: +Consider the following example: data Abyss = MkAbyss !Abyss - stareIntoTheAbyss :: Abyss -> a stareIntoTheAbyss x = case x of {} @@ -1474,7 +1482,6 @@ stareIntoTheAbyss above. Then again, the same problem occurs with recursive newtypes, like in the following code: newtype Chasm = MkChasm Chasm - gazeIntoTheChasm :: Chasm -> a gazeIntoTheChasm x = case x of {} -- Erroneously warned as non-exhaustive @@ -1498,9 +1505,26 @@ maximum recursion depth to 1 to mitigate the problem. If the branching factor is exactly 1 (i.e., we have a linear chain instead of a tree), then it's okay to stick with a larger maximum recursion depth. +In #17977 we saw that the defaultRecTcMaxBound (100 at the time of writing) was +too large and had detrimental effect on performance of the coverage checker. +Given that we only commit to a best effort anyway, we decided to substantially +decrement the recursion depth to 3, at the cost of precision in some edge cases +like + + data Nat = Z | S Nat + data Down :: Nat -> Type where + Down :: !(Down n) -> Down (S n) + f :: Down (S (S (S (S (S Z))))) -> () + f x = case x of {} + +Since the coverage won't bother to instantiate Down 4 levels deep to see that it +is in fact uninhabited, it will emit a inexhaustivity warning for the case. + +Note [Types that are definitely inhabitable] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another microoptimization applies to data types like this one: - data S a = ![a] !T + data S a = S ![a] !T Even though there is a strict field of type [a], it's quite silly to call nonVoid on it, since it's "obvious" that it is inhabitable. To make this ===================================== testsuite/tests/pmcheck/should_compile/T17977.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +module Bug where + +import Data.Kind +import Data.Type.Equality + +data Nat = Z | S Nat + +data SNat :: Nat -> Type where + SZ :: SNat Z + SS :: SNat n -> SNat (S n) + +type family S' (n :: Nat) :: Nat where + S' n = S n + +data R :: Nat -> Nat -> Nat -> Type where + MkR :: !(R m n o) -> R (S m) n (S o) + +type family NatPlus (m :: Nat) (n :: Nat) :: Nat where + NatPlus Z n = n + NatPlus (S m) n = S' (NatPlus m n) + +f :: forall (m :: Nat) (n :: Nat) (o :: Nat). + SNat m -> SNat n -> SNat o + -> R m n o -> NatPlus m n :~: o +f (SS sm) sn (SS so) (MkR r) + | Refl <- f sm sn so r + = Refl ===================================== testsuite/tests/pmcheck/should_compile/T17977b.hs ===================================== @@ -0,0 +1,24 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE EmptyCase #-} +module Bug where + +import Data.Kind + +data Nat = Z | S Nat + +data Down :: Nat -> Type where + Down :: !(Down n) -> Down (S n) + +data Up :: Nat -> Type where + Up :: !(Up (S n)) -> Up n + +f :: Down n -> () +f (Down r) = () + +f' :: Down (S (S (S (S Z)))) -> () +f' (Down r) = () + +g :: Up n -> () +g (Up r) = () ===================================== testsuite/tests/pmcheck/should_compile/T17977b.stderr ===================================== @@ -0,0 +1,4 @@ + +T17977b.hs:21:1: warning: [-Woverlapping-patterns (in -Wdefault)] + Pattern match has inaccessible right hand side + In an equation for ‘f'’: f' (Down r) = ... ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -114,6 +114,10 @@ test('T17703', normal, compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17783', normal, compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T17977', collect_compiler_stats('bytes allocated',10), compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T17977b', collect_compiler_stats('bytes allocated',10), compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b21717907a741b56513f5e1fa1ebceecf971613 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b21717907a741b56513f5e1fa1ebceecf971613 You're receiving 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 1 19:04:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 15:04:08 -0400 Subject: [Git][ghc/ghc][master] Make hadrian pass on the no-colour setting to GHC. Message-ID: <5e84e5a8624e7_61673f81cca05dd82316113@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - 1 changed file: - hadrian/src/Settings/Builders/Ghc.hs Changes: ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -29,9 +29,12 @@ toolArgs = do compileAndLinkHs :: Args compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do ways <- getLibraryWays + useColor <- shakeColor <$> expr getShakeOptions let hasVanilla = elem vanilla ways hasDynamic = elem dynamic ways mconcat [ arg "-Wall" + , not useColor ? builder (Ghc CompileHs) ? + arg "-fdiagnostics-color=never" , (hasVanilla && hasDynamic) ? builder (Ghc CompileHs) ? platformSupportsSharedLibs ? way vanilla ? arg "-dynamic-too" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c09f636a459f50119bfbb5bf798b9a9e19eb464 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c09f636a459f50119bfbb5bf798b9a9e19eb464 You're receiving 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 1 19:35:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 01 Apr 2020 15:35:54 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: PmCheck: Adjust recursion depth for inhabitation test Message-ID: <5e84ed1a5c268_61676830044231983a@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - 43608d6d by Simon Peyton Jones at 2020-04-01T15:35:25-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 0e46a528 by Sebastian Graf at 2020-04-01T15:35:26-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 30b3a1f5 by Ömer Sinan Ağacan at 2020-04-01T15:35:34-04:00 Fix a pointer format string in RTS - - - - - aa0b14e8 by Ömer Sinan Ağacan at 2020-04-01T15:35:36-04:00 Remove unused closure stg_IND_direct - - - - - 56d1e9b5 by Ben Gamari at 2020-04-01T15:35:36-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - f58d4b8d by Ryan Scott at 2020-04-01T15:35:37-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 159ea43f by Sylvain Henry at 2020-04-01T15:35:43-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - cf407bed by Ryan Scott at 2020-04-01T15:35:43-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/main/SysTools/Terminal.hs - compiler/prelude/primops.txt.pp - compiler/typecheck/TcSplice.hs - hadrian/hadrian.cabal - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Library.hs - hadrian/src/Settings/Builders/Ghc.hs - hadrian/stack.yaml - includes/stg/MiscClosures.h - rts/StgMiscClosures.cmm - rts/sm/GC.c - testsuite/tests/dependent/should_compile/dynamic-paper.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ecdc6599d4aacbc8593ef4b415b8bac7dbc789c0...cf407bed46880760bb35be268651434775c0036c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ecdc6599d4aacbc8593ef4b415b8bac7dbc789c0...cf407bed46880760bb35be268651434775c0036c You're receiving 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 1 22:07:52 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 01 Apr 2020 18:07:52 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Rework treatment of `elem`. Add UTF8 GHC.CString functions. Message-ID: <5e8510b8caf22_6167120434ec235551f@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: d6c0da22 by Andreas Klebinger at 2020-04-02T00:07:37+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. We optimize `elem` now in more ways than before. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks. These ultimately simply to a single case expression. It will also turn into a fold for dynamic lists when list fusion applies. This logic however does not work on string literals. For this reason I added a rule to do the transformation into a case explicitly via a built in rule. It will fire for any short string literals. (<=32 Bytes). Longer calls to elem on string literals are rewritten to calls to elem variants specialized to string literals. This means we will rewrite: * c `elem` (unpackCString "Foo"#) => elemCString# c' "Foo"# * c `elem` (unpackCStringUtf8 "Bär"#) => elemCStringUtf8# c' "Bär"# This means all calls to elem on string literals, as well as many on other statically known lists should now be allocation free. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors. A version of `elem` operating on known string literals was added: * elemCString# :: Char# -> Addr# -> Bool * elemCStringUtf8# :: Char# -> Addr# -> Bool - - - - - 12 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/prelude/PrelNames.hs - compiler/utils/Util.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.Make ( sortQuantVars, castBottomExpr, -- * Constructing boxed literals + trueExpr, falseExpr, mkWordExpr, mkWordExprWord, mkIntExpr, mkIntExprInt, mkIntegerExpr, mkNaturalExpr, @@ -248,6 +249,10 @@ castBottomExpr e res_ty ************************************************************************ -} +trueExpr, falseExpr :: CoreExpr +trueExpr = Var trueDataConId +falseExpr = Var falseDataConId + -- | Create a 'CoreExpr' which will evaluate to the given @Int@ mkIntExpr :: Platform -> Integer -> CoreExpr -- Result = I# i :: Int mkIntExpr platform i = mkCoreConApps intDataCon [mkIntLit platform i] ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -34,7 +34,7 @@ import GHC.Core import GHC.Core.Make import GHC.Types.Id import GHC.Types.Literal -import GHC.Core.SimpleOpt ( exprIsLiteral_maybe ) +import GHC.Core.SimpleOpt ( exprIsLiteral_maybe, exprIsLambda_maybe ) import PrimOp ( PrimOp(..), tagToEnumKey ) import TysWiredIn import TysPrim @@ -67,6 +67,8 @@ import Data.Int import Data.Ratio import Data.Word +import Encoding (utf8DecodeByteString) + {- Note [Constant folding] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1254,11 +1256,18 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, + BuiltinRule { ru_name = fsLit "AppendLitStringUtf8", + ru_fn = unpackCStringFoldrUtf8Name, + ru_nargs = 4, ru_try = match_append_lit_utf8 }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, ru_nargs = 2, ru_try = \_ _ _ -> match_inline }, + + -- See Note [Compiling `elem` on Strings] in CString.hs + BuiltinRule { ru_name = fsLit "ElemLitString", ru_fn = elemName, + ru_nargs = 4, ru_try = match_elem }, BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId, ru_nargs = 4, ru_try = \_ _ _ -> match_magicDict }, @@ -1430,11 +1439,20 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo" c (unpackFoldrCString*# "baz" c n) +-- = unpackFoldrCString*# "foobaz" c n + +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey + +-- CStringUTF8 version +match_append_lit_utf8 :: RuleFun +match_append_lit_utf8 = match_append_lit unpackCStringFoldrUtf8IdKey -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,7 +1465,7 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey + , unpk `hasKey` foldVariant , cheapEqExpr' tickishFloatable c1 c2 , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 , c2Ticks <- stripTicksTopT tickishFloatable c2 @@ -1460,23 +1478,62 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)) = s1==s2 +-- Also matches unpackCStringUtf8# match_eq_string :: RuleFun match_eq_string _ id_unf _ [Var unpk1 `App` lit1, Var unpk2 `App` lit2] - | unpk1 `hasKey` unpackCStringIdKey - , unpk2 `hasKey` unpackCStringIdKey + | unpk_key1 <- getUnique unpk1 + , unpk_key2 <- getUnique unpk2 + , unpk_key1 == unpk_key2 + , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 = Just (if s1 == s2 then trueValBool else falseValBool) match_eq_string _ _ _ _ = Nothing +--------------------------------------------------- +-- The rule is this: +-- elem x (build ((unpackFoldrCString# "abc"#))) +-- = case x of +-- 'a'# -> True +-- 'b'# -> True +-- 'c'# -> True +-- _ -> False +-- +-- Only matches short string (<20 bytes). +-- Also matches unpackCStringUtf8# +-- See Note [Compiling `elem` on Strings] in CString.hs + +match_elem :: RuleFun +match_elem _ id_unf _ [Type ty, _dict, x, xs] + | ty `eqType` charTy + , ( xsTicks + , Var build `App` _char_ty `App` unf_str_app) + <- stripTicksTop tickishFloatable xs + , Just (_arg, (Var unfold_str `App` _ty2 `App` lit1), lam_ticks) + <- exprIsLambda_maybe id_unf unf_str_app + , build `hasKey` buildIdKey + , getUnique unfold_str `elem` [unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey] + , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 + , BS.length s1 <= 32 + = let elem_string = nubSort $ utf8DecodeByteString s1 :: String + x_id = mkWildValBinder charTy :: Id + x_prim_id = mkWildValBinder charPrimTy :: Id + switch = Case (Var x_prim_id) x_prim_id boolTy + ((DEFAULT, [], falseExpr):foldr mkCharAlt [] elem_string) + mkCharAlt :: Char -> [CoreAlt] -> [CoreAlt] + mkCharAlt c alts = (LitAlt (mkLitChar c), [], trueExpr):alts + in Just $ mkTicks (xsTicks ++ lam_ticks) + $ Case x x_id boolTy [(DataAlt charDataCon, [x_id], switch)] + +match_elem _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -340,8 +340,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, -- Overloaded lists isListClassName, @@ -352,6 +352,7 @@ basicKnownKeyNames -- List operations concatName, filterName, mapName, zipName, foldrName, buildName, augmentName, appendName, + elemName, -- FFI primitive types that are not wired-in. stablePtrTyConName, ptrTyConName, funPtrTyConName, @@ -677,9 +678,10 @@ ordClass_RDR = nameRdrName ordClassName enumClass_RDR = nameRdrName enumClassName monadClass_RDR = nameRdrName monadClassName -map_RDR, append_RDR :: RdrName +map_RDR, append_RDR, elem_RDR :: RdrName map_RDR = nameRdrName mapName append_RDR = nameRdrName appendName +elem_RDR = nameRdrName elemName foldr_RDR, build_RDR, returnM_RDR, bindM_RDR, failM_RDR :: RdrName @@ -712,11 +714,12 @@ ioDataCon_RDR :: RdrName ioDataCon_RDR = nameRdrName ioDataConName eqString_RDR, unpackCString_RDR, unpackCStringFoldr_RDR, - unpackCStringUtf8_RDR :: RdrName + unpackCStringFoldrUtf8_RDR, unpackCStringUtf8_RDR :: RdrName eqString_RDR = nameRdrName eqStringName unpackCString_RDR = nameRdrName unpackCStringName unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name +unpackCStringFoldrUtf8_RDR = nameRdrName unpackCStringFoldrUtf8Name newStablePtr_RDR :: RdrName newStablePtr_RDR = nameRdrName newStablePtrName @@ -1006,11 +1009,12 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name,eqStringName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -1083,7 +1087,7 @@ groupWithName = varQual gHC_EXTS (fsLit "groupWith") groupWithIdKey -- Random PrelBase functions fromStringName, otherwiseIdName, foldrName, buildName, augmentName, - mapName, appendName, assertName, + mapName, appendName, elemName, assertName, breakpointName, breakpointCondName, opaqueTyConName, dollarName :: Name dollarName = varQual gHC_BASE (fsLit "$") dollarIdKey @@ -1097,6 +1101,7 @@ assertName = varQual gHC_BASE (fsLit "assert") assertIdKey breakpointName = varQual gHC_BASE (fsLit "breakpoint") breakpointIdKey breakpointCondName= varQual gHC_BASE (fsLit "breakpointCond") breakpointCondIdKey opaqueTyConName = tcQual gHC_BASE (fsLit "Opaque") opaqueTyConKey +elemName = varQual gHC_LIST (fsLit "elem") elemIdKey fromStringName = varQual dATA_STRING (fsLit "fromString") fromStringClassOpKey -- PrelTup @@ -2081,13 +2086,15 @@ unsafeReflDataConKey = mkPreludeDataConUnique 114 -} wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, + elemIdKey, buildIdKey, errorIdKey, foldrIdKey, recSelErrorIdKey, seqIdKey, eqStringIdKey, noMethodBindingErrorIdKey, nonExhaustiveGuardsErrorIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey :: Unique @@ -2095,27 +2102,29 @@ wildCardKey = mkPreludeMiscIdUnique 0 -- See Note [WildCard absentErrorIdKey = mkPreludeMiscIdUnique 1 augmentIdKey = mkPreludeMiscIdUnique 2 appendIdKey = mkPreludeMiscIdUnique 3 -buildIdKey = mkPreludeMiscIdUnique 4 -errorIdKey = mkPreludeMiscIdUnique 5 -foldrIdKey = mkPreludeMiscIdUnique 6 -recSelErrorIdKey = mkPreludeMiscIdUnique 7 -seqIdKey = mkPreludeMiscIdUnique 8 -absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 9 -eqStringIdKey = mkPreludeMiscIdUnique 10 -noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 11 -nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 12 -runtimeErrorIdKey = mkPreludeMiscIdUnique 13 -patErrorIdKey = mkPreludeMiscIdUnique 14 -realWorldPrimIdKey = mkPreludeMiscIdUnique 15 -recConErrorIdKey = mkPreludeMiscIdUnique 16 -unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 17 -unpackCStringAppendIdKey = mkPreludeMiscIdUnique 18 -unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 19 -unpackCStringIdKey = mkPreludeMiscIdUnique 20 -voidPrimIdKey = mkPreludeMiscIdUnique 21 -typeErrorIdKey = mkPreludeMiscIdUnique 22 -divIntIdKey = mkPreludeMiscIdUnique 23 -modIntIdKey = mkPreludeMiscIdUnique 24 +elemIdKey = mkPreludeMiscIdUnique 4 +buildIdKey = mkPreludeMiscIdUnique 5 +errorIdKey = mkPreludeMiscIdUnique 6 +foldrIdKey = mkPreludeMiscIdUnique 7 +recSelErrorIdKey = mkPreludeMiscIdUnique 8 +seqIdKey = mkPreludeMiscIdUnique 9 +absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 10 +eqStringIdKey = mkPreludeMiscIdUnique 11 +noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 12 +nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 13 +runtimeErrorIdKey = mkPreludeMiscIdUnique 14 +patErrorIdKey = mkPreludeMiscIdUnique 15 +realWorldPrimIdKey = mkPreludeMiscIdUnique 16 +recConErrorIdKey = mkPreludeMiscIdUnique 17 +unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 18 +unpackCStringAppendIdKey = mkPreludeMiscIdUnique 19 +unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 20 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 21 +unpackCStringIdKey = mkPreludeMiscIdUnique 22 +voidPrimIdKey = mkPreludeMiscIdUnique 23 +typeErrorIdKey = mkPreludeMiscIdUnique 24 +divIntIdKey = mkPreludeMiscIdUnique 25 +modIntIdKey = mkPreludeMiscIdUnique 26 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== compiler/utils/Util.hs ===================================== @@ -637,7 +637,6 @@ ordNub xs | Set.member x s = go s xs | otherwise = x : go (Set.insert x s) xs - {- ************************************************************************ * * ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1618,7 +1618,11 @@ iShiftRL# :: Int# -> Int# -> Int# a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# | otherwise = a `uncheckedIShiftRL#` b +------------------------------------------------------------------------ -- Rules for C strings (the functions themselves are now in GHC.CString) +------------------------------------------------------------------------ + +-- Ascii variants {-# RULES "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a @@ -1628,3 +1632,14 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n #-} + +-- Utf8 variants +{-# RULES +"unpackUtf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-listUtf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-appendUtf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + +-- There's a built-in rule (in PrelRules.hs) for +-- unpackFoldrUtf8 "föö" c (unpackFoldrUtf8 "bäz" c n) = unpackFoldrUtf8 "fööbäz" c n + + #-} ===================================== libraries/base/GHC/List.hs ===================================== @@ -1147,10 +1147,17 @@ elem x = any (== x) #else elem _ [] = False elem x (y:ys) = x==y || elem x ys -{-# NOINLINE [1] elem #-} +{-# NOINLINE elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False +-- See Note [Compiling `elem` on Strings] in CString.hs +"elem at CString/unpack" [0] forall (x :: Char) (addr :: Addr#) + . elem x (unpackCString# addr) + = x `elemCString#` addr +"elem at CStringUtf8/unpack" [0] forall (x :: Char) (addr :: Addr#) + . elem x (unpackCStringUtf8# addr) + = x `elemCStringUtf8#` addr #-} #endif @@ -1172,10 +1179,17 @@ notElem x = all (/= x) #else notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys -{-# NOINLINE [1] notElem #-} +{-# NOINLINE notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True +-- See Note [Compiling `elem` on Strings] in CString.hs +"notElem at CString/unpack" [0] forall (x :: Char) (addr :: Addr#) + . notElem x (unpackCString# addr) + = not (x `elemCString#` addr) +"notElem at CStringUtf8/unpack" [0] forall (x :: Char) (addr :: Addr#) + . notElem x (unpackCStringUtf8# addr) + = not (x `elemCStringUtf8#` addr) #-} #endif ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,17 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques + # We only grep for specific patterns to minimize failures when eg core syntax changes + # We expect two unfolds using eqChar + echo $$(cat T17752.dump-simpl | grep unpackFoldrCString) + echo $$(cat T17752.dump-simpl | grep eqChar) + # And two pattern matches + echo $$(cat T17752.dump-simpl | grep "case x1" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,82 @@ +module T17752 where + +-- Should compile to unfoldCStr if the rules fire +isElemLit x = x `elem` "theQuickShinyGHCJumpsOverTheRuleRecursion" +isNotElemLit x = x `notElem` "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion" + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +{- + +Should the grep tests fail make sure the core still behaves +like the one below (or better!) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isElemLit1 = "theQuickShinyGHCJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 20, types: 9, coercions: 0, joins: 0/0} +isElemLit + = \ x -> + unpackFoldrCString# + isElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isNotElemLit1 + = "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 25, types: 10, coercions: 0, joins: 0/0} +isNotElemLit + = \ x -> + case unpackFoldrCString# + isNotElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + of { + False -> True; + True -> False + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'a'# -> True; + 'b'# -> True; + 'c'# -> True + } + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isNotElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'x'# -> True; + 'y'# -> True; + 'z'# -> True + } + } +-} ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,25 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) +GHC.CString.unpackFoldrCString# + case GHC.CString.unpackFoldrCString# +case GHC.Prim.eqChar# x1 y1 of { + case GHC.Prim.eqChar# x1 y1 of { +case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) \ No newline at end of file ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns #-} +{-# OPTIONS -fregs-graph #-} -- Needed for elemCString#, see #17823 ----------------------------------------------------------------------------- -- | @@ -17,8 +18,16 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + elemCString#, + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + elemCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types @@ -71,8 +80,22 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [NOINLINE for unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n +At one stage I had NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. BUT there may be a lot of +literal strings, and making a separate 'unpack' loop for +each is highly gratuitous. See nofib/real/anna/PrettyPrint. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +112,64 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. +If we use the offset start off with the increment and an addition +to get the real address. Which might not be optimized aways. + + Note [Compiling `elem` on Strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The pattern f c = c `elem` "" is quite common in +parsers and the like and can be quite performance critical. + +The fastest way to process this pattern is to transform it +into a case. That is we transform: + + x `elem` "xy" +=> + case x of + 'x' -> True + 'y' -> True + _ -> False + +For this reason there is a BUILTIN rule "ElemLitString" which +performs this rewrite early in the pipeline in case "xy" is built +from unpacking a string literal of small size. + +For long strings however we avoid doing this translation as +it would impact code size negatively. + +However we do not want to fall back to allocating a String and +then calling elem onto it. So towards the end of the pipeline +we use rewrite it into a more efficient form working of the +unboxed string literal. + +Implementing this in terms of unpackFoldrCString# is not possible +without allocating. As the folding function would have to capture +the element we look for. + +Instead we rewrite to a spezialized version of elem, `elemCString#` +which works over unboxed string literals. + + Note [Inlining of elemCString#] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We inline both elemCString*# variants in the hope to cancel out the unboxing +of the otherwise lazy character argument. + +For elemCString# we allow inlining the inner loop as it's tiny comming in +at less than 40bytes on x64. This comes out to about the same size of the +size overhead we pay for a non-tail call. Not to speak of eliminating the +runtime overhead of the call. + +For elemCStringUtf8# this is different. The whole unicode logic makes it large +enough to make inlining a bad choice. So we use the magic `noinline` to avoid +the inner loop containing the utf8 logic to be inlined. Given the additional +overhead of unicode decoding the call overhead is also less significant so it's +not as big of a loss. + -} unpackCString# :: Addr# -> [Char] @@ -111,22 +192,9 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - +-- See Note [NOINLINE for unpackFoldrCString] {-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a unpackFoldrCString# addr f z | isTrue# (ch `eqChar#` '\0'#) = z | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z @@ -134,32 +202,101 @@ unpackFoldrCString# addr f z -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# +-- See Note [Compiling `elem` on Strings] +-- See Note [Inlining of elemCString#] +{-# INLINE elemCString# #-} +elemCString# :: Char -> Addr# -> Bool +elemCString# c base_addr = + let !ch = (indexCharOffAddr# base_addr 0#) + in -- We check for end-of-string first to preserve laziness + -- of the Char argument. + case ch of + '\0'# -> False + _ -> case c of + C# c' -> check c' ch base_addr + where + -- Invariant: ch != '\NULL' + check :: Char# -> Char# -> Addr# -> Bool + check c_ub ch addr + | isTrue# (ch `eqChar#` c_ub ) = True + | True = + let !addr' = (addr `plusAddr#` 1#) + in case indexCharOffAddr# addr' 0# of + '\0'# -> False + next_ch -> check c_ub next_ch addr' + -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# +-- See Note [NOINLINE for unpackFoldrCString] +{-# NOINLINE unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr f z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` unpackFoldrCStringUtf8# addr' f z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of elemCString#] +-- See Note [Compiling `elem` on Strings] +{-# INLINE elemCStringUtf8# #-} +elemCStringUtf8# :: Char -> Addr# -> Bool +elemCStringUtf8# c base_addr = + let !ch = (indexCharOffAddr# base_addr 0#) + in -- We check for end-of-string first to preserve laziness + -- of the Char argument. + case ch of + '\0'# -> False + _ -> case c of + C# c' -> elemCStringUtf8_check# c' ch base_addr + +-- Local to elemCStringUtf8#, defined at the top to avoid unfolding it +-- into use sites. +-- Invariant: ch != '\NULL' +{-# NOINLINE elemCStringUtf8_check# #-} +elemCStringUtf8_check# :: Char# -> Char# -> Addr# -> Bool +elemCStringUtf8_check# c_ub ch addr = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in if (isTrue# (utf_ch `eqChar#` c_ub)) + then True + else case (indexCharOffAddr# addr' 0#) of + '\0'# -> False + ch' -> elemCStringUtf8_check# c_ub ch' addr' + -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. unpackNBytes# :: Addr# -> Int# -> [Char] @@ -174,3 +311,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explizit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,17 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- Added to `GHC.CString`: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + elemCString# :: Char# -> Addr# -> Bool + elemCStringUtf8# :: Char# -> Addr# -> Bool + + `elemCString*#` is a version of `elem` specialized for operations + over GHC String literals. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6c0da2267233daddc6d2f96013ec1394bf588e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6c0da2267233daddc6d2f96013ec1394bf588e4 You're receiving 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 1 23:04:08 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Wed, 01 Apr 2020 19:04:08 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] WIP on in-tree annotations Message-ID: <5e851de8be5f5_6167120434ec2360897@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: 069d05b4 by Alan Zimmerman at 2020-04-02T00:03:28+01:00 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them - - - - - 28 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/ThToHs.hs - compiler/main/HeaderInfo.hs - compiler/main/HscStats.hs - compiler/parser/Lexer.x - compiler/parser/Parser.y - compiler/parser/RdrHsSyn.hs - compiler/typecheck/TcBackpack.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcRnDriver.hs - compiler/typecheck/TcRnExports.hs - compiler/typecheck/TcRnMonad.hs - compiler/typecheck/TcRnTypes.hs - compiler/typecheck/TcRules.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/utils/OrdList.hs Changes: ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -695,6 +695,7 @@ summariseRequirement pn mod_name = do ms_textual_imps = extra_sig_imports, ms_parsed_mod = Just (HsParsedModule { hpm_module = L loc (HsModule { + hsmodAnn = noAnn, hsmodName = Just (L loc mod_name), hsmodExports = Nothing, hsmodImports = [], ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -394,7 +394,8 @@ hscParse' mod_summary srcs2 <- liftIO $ filterM doesFileExist srcs1 let api_anns = ApiAnns { - apiAnnItems = M.fromListWith (++) $ annotations pst, + -- AZ apiAnnItems = M.fromListWith (++) $ annotations pst, + apiAnnItems = M.empty, apiAnnEofPos = eof_pos pst, apiAnnComments = M.fromList (annotations_comments pst), apiAnnRogueComments = comment_q pst @@ -991,9 +992,9 @@ hscCheckSafeImports tcg_env = do warns dflags rules = listToBag $ map (warnRules dflags) rules - warnRules :: DynFlags -> GenLocated SrcSpan (RuleDecl GhcTc) -> ErrMsg + warnRules :: DynFlags -> LRuleDecl GhcTc -> ErrMsg warnRules dflags (L loc (HsRule { rd_name = n })) = - mkPlainWarnMsg dflags loc $ + mkPlainWarnMsg dflags (locA loc) $ text "Rule \"" <> ftext (snd $ unLoc n) <> text "\" ignored" $+$ text "User defined rules are disabled under Safe Haskell" warnRules _ (L _ (XRuleDecl nec)) = noExtCon nec ===================================== compiler/GHC/Hs.hs ===================================== @@ -63,10 +63,11 @@ import Data.Data hiding ( Fixity ) -- All we actually declare here is the top-level structure for a module. data HsModule = HsModule { + hsmodAnn :: ApiAnn, hsmodName :: Maybe (Located ModuleName), -- ^ @Nothing@: \"module X where\" is omitted (in which case the next -- field is Nothing too) - hsmodExports :: Maybe (Located [LIE GhcPs]), + hsmodExports :: Maybe (LocatedA [LIE GhcPs]), -- ^ Export list -- -- - @Nothing@: export list omitted, so export everything @@ -86,7 +87,7 @@ data HsModule -- downstream. hsmodDecls :: [LHsDecl GhcPs], -- ^ Type, class, value, and interface signature decls - hsmodDeprecMessage :: Maybe (Located WarningTxt), + hsmodDeprecMessage :: Maybe (LocatedA WarningTxt), -- ^ reason\/explanation for warning/deprecation of this module -- -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnOpen' @@ -116,11 +117,11 @@ deriving instance Data HsModule instance Outputable HsModule where - ppr (HsModule Nothing _ imports decls _ mbDoc) + ppr (HsModule _ Nothing _ imports decls _ mbDoc) = pp_mb mbDoc $$ pp_nonnull imports $$ pp_nonnull decls - ppr (HsModule (Just name) exports imports decls deprec mbDoc) + ppr (HsModule _ (Just name) exports imports decls deprec mbDoc) = vcat [ pp_mb mbDoc, case exports of ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -1135,11 +1135,17 @@ type LInjectivityAnn pass = Located (InjectivityAnn pass) -- -- This will be represented as "InjectivityAnn `r` [`a`, `c`]" data InjectivityAnn pass - = InjectivityAnn (LocatedA (IdP pass)) [LocatedA (IdP pass)] + = InjectivityAnn (XCInjectivityAnn pass) + (LocatedA (IdP pass)) [LocatedA (IdP pass)] -- ^ - 'ApiAnnotation.AnnKeywordId' : -- 'ApiAnnotation.AnnRarrow', 'ApiAnnotation.AnnVbar' -- For details on above see note [Api annotations] in ApiAnnotation + | XInjectivityAnn !(XXInjectivityAnn pass) + +type instance XCInjectivityAnn (GhcPass _) = ApiAnn +type instance XXInjectivityAnn (GhcPass _) = NoExtCon + data FamilyInfo pass = DataFamily @@ -1201,8 +1207,9 @@ pprFamilyDecl top_level (FamilyDecl { fdInfo = info, fdLName = ltycon TyVarSig _ tv_bndr -> text "=" <+> ppr tv_bndr XFamilyResultSig nec -> noExtCon nec pp_inj = case mb_inj of - Just (L _ (InjectivityAnn lhs rhs)) -> + Just (L _ (InjectivityAnn _ lhs rhs)) -> hsep [ vbar, ppr lhs, text "->", hsep (map ppr rhs) ] + Just (L _ (XInjectivityAnn nec)) -> noExtCon nec Nothing -> empty (pp_where, pp_eqns) = case info of ClosedTypeFamily mb_eqns -> @@ -1628,7 +1635,7 @@ free-standing `type instance` declaration. ----------------- Type synonym family instances ------------- -- | Located Type Family Instance Equation -type LTyFamInstEqn pass = Located (TyFamInstEqn pass) +type LTyFamInstEqn pass = LocatedA (TyFamInstEqn pass) -- ^ May have 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi' -- when in a list @@ -1741,7 +1748,7 @@ data FamEqn pass rhs -- For details on above see note [Api annotations] in ApiAnnotation -type instance XCFamEqn (GhcPass _) r = NoExtField +type instance XCFamEqn (GhcPass _) r = ApiAnn type instance XXFamEqn (GhcPass _) r = NoExtCon ----------------- Class instances ------------- @@ -1760,7 +1767,7 @@ data ClsInstDecl pass , cid_sigs :: [LSig pass] -- User-supplied pragmatic info , cid_tyfam_insts :: [LTyFamInstDecl pass] -- Type family instances , cid_datafam_insts :: [LDataFamInstDecl pass] -- Data family instances - , cid_overlap_mode :: Maybe (Located OverlapMode) + , cid_overlap_mode :: Maybe (LocatedA OverlapMode) -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen', -- 'ApiAnnotation.AnnClose', @@ -1922,7 +1929,7 @@ ppDerivStrategy mb = Nothing -> empty Just (L _ ds) -> ppr ds -ppOverlapPragma :: Maybe (Located OverlapMode) -> SDoc +ppOverlapPragma :: Maybe (LocatedA OverlapMode) -> SDoc ppOverlapPragma mb = case mb of Nothing -> empty @@ -1982,7 +1989,7 @@ data DerivDecl pass = DerivDecl -- See Note [Inferring the instance context] in TcDerivInfer. , deriv_strategy :: Maybe (LDerivStrategy pass) - , deriv_overlap_mode :: Maybe (Located OverlapMode) + , deriv_overlap_mode :: Maybe (LocatedA OverlapMode) -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDeriving', -- 'ApiAnnotation.AnnInstance', 'ApiAnnotation.AnnStock', -- 'ApiAnnotation.AnnAnyClass', 'Api.AnnNewtype', @@ -2170,11 +2177,11 @@ data ForeignDecl pass such as Int and IO that we know how to make foreign calls with. -} -type instance XForeignImport GhcPs = NoExtField +type instance XForeignImport GhcPs = ApiAnn type instance XForeignImport GhcRn = NoExtField type instance XForeignImport GhcTc = Coercion -type instance XForeignExport GhcPs = NoExtField +type instance XForeignExport GhcPs = ApiAnn type instance XForeignExport GhcRn = NoExtField type instance XForeignExport GhcTc = Coercion @@ -2292,7 +2299,7 @@ type instance XCRuleDecls GhcTc = NoExtField type instance XXRuleDecls (GhcPass _) = NoExtCon -- | Located Rule Declaration -type LRuleDecl pass = Located (RuleDecl pass) +type LRuleDecl pass = LocatedA (RuleDecl pass) -- | Rule Declaration data RuleDecl pass @@ -2322,7 +2329,7 @@ data RuleDecl pass data HsRuleRn = HsRuleRn NameSet NameSet -- Free-vars from the LHS and RHS deriving Data -type instance XHsRule GhcPs = NoExtField +type instance XHsRule GhcPs = ApiAnn type instance XHsRule GhcRn = HsRuleRn type instance XHsRule GhcTc = HsRuleRn ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -261,6 +261,20 @@ data SrcSpanAnn = SrcSpanAnn { ann :: ApiAnn, locA :: SrcSpan } instance Outputable SrcSpanAnn where ppr (SrcSpanAnn a l) = text "SrcSpanAnn" <+> ppr a <+> ppr l +-- --------------------------------------------------------------------- +-- Managing annotations for lists +-- --------------------------------------------------------------------- + +data AnnList + = AnnList { + alOpenLoc :: SrcSpan, + alOpenKeyword :: AnnKeywordId, + alCloseLoc :: SrcSpan, + alCloseKeyword :: AnnKeywordId + } deriving (Data) + +-- --------------------------------------------------------------------- + reAnn :: [AddApiAnn] -> ApiAnnComments -> Located a -> LocatedA a reAnn anns cs (L l a) = L (SrcSpanAnn (ApiAnn anns cs) l) a @@ -559,6 +573,11 @@ type family XXAnnDecl x type family XCRoleAnnotDecl x type family XXRoleAnnotDecl x +-- ------------------------------------- +-- InjectivityAnn type families +type family XCInjectivityAnn x +type family XXInjectivityAnn x + -- ===================================================================== -- Type families for the HsExpr extension points @@ -826,9 +845,6 @@ type family XIEDoc x type family XIEDocNamed x type family XXIE x --- ------------------------------------- - - -- ===================================================================== -- End of Type family definitions -- ===================================================================== ===================================== compiler/GHC/Hs/ImpExp.hs ===================================== @@ -43,7 +43,7 @@ One per \tr{import} declaration in a module. -} -- | Located Import Declaration -type LImportDecl pass = Located (ImportDecl pass) +type LImportDecl pass = LocatedA (ImportDecl pass) -- ^ When in a list this may have -- -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi' @@ -88,7 +88,7 @@ data ImportDecl pass ideclQualified :: ImportDeclQualifiedStyle, -- ^ If/how the import is qualified. ideclImplicit :: Bool, -- ^ True => implicit import (of Prelude) ideclAs :: Maybe (Located ModuleName), -- ^ as Module - ideclHiding :: Maybe (Bool, Located [LIE pass]) + ideclHiding :: Maybe (Bool, LocatedA [LIE pass]) -- ^ (True => hiding, names) } | XImportDecl (XXImportDecl pass) @@ -197,7 +197,7 @@ type LIEWrappedName name = Located (IEWrappedName name) -- | Located Import or Export -type LIE pass = Located (IE pass) +type LIE pass = LocatedA (IE pass) -- ^ When in a list this may have -- -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnComma' ===================================== compiler/GHC/HsToCore.hs ===================================== @@ -379,7 +379,7 @@ dsRule (L loc (HsRule { rd_name = name , rd_tmvs = vars , rd_lhs = lhs , rd_rhs = rhs })) - = putSrcSpanDs loc $ + = putSrcSpanDs (locA loc) $ do { let bndrs' = [var | L _ (RuleBndr _ (L _ var)) <- vars] ; lhs' <- unsetGOptM Opt_EnableRewriteRules $ ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -598,7 +598,7 @@ repInjectivityAnn :: Maybe (LInjectivityAnn GhcRn) -> MetaM (Core (Maybe TH.InjectivityAnn)) repInjectivityAnn Nothing = do { coreNothing injAnnTyConName } -repInjectivityAnn (Just (L _ (InjectivityAnn lhs rhs))) = +repInjectivityAnn (Just (L _ (InjectivityAnn _ lhs rhs))) = do { lhs' <- lookupBinder (unLoc lhs) ; rhs1 <- mapM (lookupBinder . unLoc) rhs ; rhs2 <- coreList nameTyConName rhs1 @@ -840,7 +840,7 @@ repRuleD (L loc (HsRule { rd_name = n ; rhs' <- repLE rhs ; repPragRule n' ty_bndrs' tm_bndrs' lhs' rhs' act' } ; wrapGenSyms ss rule } - ; return (loc, rule) } + ; return (locA loc, rule) } repRuleD (L _ (XRuleDecl nec)) = noExtCon nec ruleBndrNames :: LRuleBndr GhcRn -> [Name] ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1344,11 +1344,11 @@ instance ToHie (LFamilyDecl GhcRn) where instance ToHie (FamilyInfo GhcRn) where toHie (ClosedTypeFamily (Just eqns)) = concatM $ - [ concatMapM (pure . locOnly . getLoc) eqns + [ concatMapM (pure . locOnly . getLocA) eqns , toHie $ map go eqns ] where - go (L l ib) = TS (ResolvedScopes [mkScope l]) ib + go (L l ib) = TS (ResolvedScopes [mkScope (locA l)]) ib toHie _ = pure [] instance ToHie (RScoped (LFamilyResultSig GhcRn)) where @@ -1389,7 +1389,7 @@ instance (ToHie rhs, HasLoc rhs) instance ToHie (LInjectivityAnn GhcRn) where toHie (L span ann) = concatM $ makeNode ann span : case ann of - InjectivityAnn lhs rhs -> + InjectivityAnn _ lhs rhs -> [ toHie $ C Use lhs , toHie $ map (C Use) rhs ] @@ -1425,8 +1425,8 @@ instance ToHie (Located (DerivStrategy GhcRn)) where NewtypeStrategy _ -> [] ViaStrategy s -> [ toHie $ TS (ResolvedScopes []) s ] -instance ToHie (Located OverlapMode) where - toHie (L span _) = pure $ locOnly span +instance ToHie (LocatedA OverlapMode) where + toHie (L span _) = pure $ locOnly (locA span) instance ToHie (LConDecl GhcRn) where toHie (L span decl) = concatM $ makeNode decl span : case decl of @@ -1863,10 +1863,10 @@ instance ToHie (LRuleDecls GhcRn) where instance ToHie (LRuleDecl GhcRn) where toHie (L _ (XRuleDecl _)) = pure [] toHie (L span r@(HsRule _ rname _ tybndrs bndrs exprA exprB)) = concatM - [ makeNode r span + [ makeNode r (locA span) , pure $ locOnly $ getLoc rname , toHie $ fmap (tvScopes (ResolvedScopes []) scope) tybndrs - , toHie $ map (RS $ mkScope span) bndrs + , toHie $ map (RS $ mkScope (locA span)) bndrs , toHie exprA , toHie exprB ] @@ -1887,7 +1887,7 @@ instance ToHie (RScoped (LRuleBndr GhcRn)) where XRuleBndr _ -> [] instance ToHie (LImportDecl GhcRn) where - toHie (L span decl) = concatM $ makeNode decl span : case decl of + toHie (L span decl) = concatM $ makeNode decl (locA span) : case decl of ImportDecl { ideclName = name, ideclAs = as, ideclHiding = hidden } -> [ toHie $ IEC Import name , toHie $ fmap (IEC ImportAs) as @@ -1896,14 +1896,14 @@ instance ToHie (LImportDecl GhcRn) where XImportDecl _ -> [] where goIE (hiding, (L sp liens)) = concatM $ - [ pure $ locOnly sp + [ pure $ locOnly (locA sp) , toHie $ map (IEC c) liens ] where c = if hiding then ImportHiding else Import instance ToHie (IEContext (LIE GhcRn)) where - toHie (IEC c (L span ie)) = concatM $ makeNode ie span : case ie of + toHie (IEC c (L span ie)) = concatM $ makeNode ie (locA span) : case ie of IEVar _ n -> [ toHie $ IEC c n ] ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -273,7 +273,7 @@ rnImportDecl this_mod , ideclSource = want_boot, ideclSafe = mod_safe , ideclQualified = qual_style, ideclImplicit = implicit , ideclAs = as_mod, ideclHiding = imp_details })) - = setSrcSpan loc $ do + = setSrcSpan (locA loc) $ do when (isJust mb_pkg) $ do pkg_imports <- xoptM LangExt.PackageImports @@ -343,7 +343,7 @@ rnImportDecl this_mod let qual_mod_name = fmap unLoc as_mod `orElse` imp_mod_name imp_spec = ImpDeclSpec { is_mod = imp_mod_name, is_qual = qual_only, - is_dloc = loc, is_as = qual_mod_name } + is_dloc = locA loc, is_as = qual_mod_name } -- filter the imports according to the import declaration (new_imp_details, gres) <- filterImports iface imp_spec imp_details @@ -364,7 +364,7 @@ rnImportDecl this_mod let imv = ImportedModsVal { imv_name = qual_mod_name - , imv_span = loc + , imv_span = locA loc , imv_is_safe = mod_safe' , imv_is_hiding = is_hiding , imv_all_exports = potential_gres @@ -906,8 +906,8 @@ although we never look up data constructors. filterImports :: ModIface -> ImpDeclSpec -- The span for the entire import decl - -> Maybe (Bool, Located [LIE GhcPs]) -- Import spec; True => hiding - -> RnM (Maybe (Bool, Located [LIE GhcRn]), -- Import spec w/ Names + -> Maybe (Bool, LocatedA [LIE GhcPs]) -- Import spec; True => hiding + -> RnM (Maybe (Bool, LocatedA [LIE GhcRn]), -- Import spec w/ Names [GlobalRdrElt]) -- Same again, but in GRE form filterImports iface decl_spec Nothing = return (Nothing, gresFromAvails (Just imp_spec) (mi_exports iface)) @@ -967,7 +967,7 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items)) lookup_lie :: LIE GhcPs -> TcRn [(LIE GhcRn, AvailInfo)] lookup_lie (L loc ieRdr) - = do (stuff, warns) <- setSrcSpan loc $ + = do (stuff, warns) <- setSrcSpan (locA loc) $ liftM (fromMaybe ([],[])) $ run_lookup (lookup_ie ieRdr) mapM_ emit_warning warns @@ -1156,7 +1156,8 @@ gresFromIE decl_spec (L loc ie, avail) prov_fn name = Just (ImpSpec { is_decl = decl_spec, is_item = item_spec }) where - item_spec = ImpSome { is_explicit = is_explicit name, is_iloc = loc } + item_spec = ImpSome { is_explicit = is_explicit name + , is_iloc = locA loc } {- @@ -1399,7 +1400,7 @@ findImportUsage imports used_gres unused_decl decl@(L loc (ImportDecl { ideclHiding = imps })) = (decl, used_gres, nameSetElemsStable unused_imps) where - used_gres = lookupSrcLoc (srcSpanEnd loc) import_usage + used_gres = lookupSrcLoc (srcSpanEnd $ locA loc) import_usage -- srcSpanEnd: see Note [The ImportMap] `orElse` [] @@ -1499,7 +1500,7 @@ warnUnusedImport flag fld_env (L loc decl, used, unused) -- Nothing used; drop entire declaration | null used - = addWarnAt (Reason flag) loc msg1 + = addWarnAt (Reason flag) (locA loc) msg1 -- Everything imported is used; nop | null unused @@ -1507,7 +1508,7 @@ warnUnusedImport flag fld_env (L loc decl, used, unused) -- Some imports are unused | otherwise - = addWarnAt (Reason flag) loc msg2 + = addWarnAt (Reason flag) (locA loc) msg2 where msg1 = vcat [ pp_herald <+> quotes pp_mod <+> is_redundant ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -244,6 +244,9 @@ addTcgDUs tcg_env dus = tcg_env { tcg_dus = tcg_dus tcg_env `plusDU` dus } rnList :: (a -> RnM (b, FreeVars)) -> [Located a] -> RnM ([Located b], FreeVars) rnList f xs = mapFvRn (wrapLocFstM f) xs +rnListA :: (a -> RnM (b, FreeVars)) -> [LocatedA a] -> RnM ([LocatedA b], FreeVars) +rnListA f xs = mapFvRn (wrapLocFstMA f) xs + {- ********************************************************* * * @@ -750,7 +753,7 @@ rnFamInstEqn doc atfi rhs_kvars ; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances] , hsib_body - = FamEqn { feqn_ext = noExtField + = FamEqn { feqn_ext = noAnn , feqn_tycon = tycon' , feqn_bndrs = bndrs' <$ mb_bndrs , feqn_pats = pats' @@ -999,7 +1002,7 @@ standaloneDerivErr rnHsRuleDecls :: RuleDecls GhcPs -> RnM (RuleDecls GhcRn, FreeVars) rnHsRuleDecls (HsRules { rds_src = src , rds_rules = rules }) - = do { (rn_rules,fvs) <- rnList rnHsRuleDecl rules + = do { (rn_rules,fvs) <- rnListA rnHsRuleDecl rules ; return (HsRules { rds_ext = noExtField , rds_src = src , rds_rules = rn_rules }, fvs) } @@ -1905,7 +1908,7 @@ rnFamDecl mb_cls (FamilyDecl { fdLName = tycon, fdTyVars = tyvars -> FamilyInfo GhcPs -> RnM (FamilyInfo GhcRn, FreeVars) rn_info (L _ fam_name) (ClosedTypeFamily (Just eqns)) = do { (eqns', fvs) - <- rnList (rnTyFamInstEqn NonAssocTyFamEqn (ClosedTyFam tycon fam_name)) + <- rnListA (rnTyFamInstEqn NonAssocTyFamEqn (ClosedTyFam tycon fam_name)) -- no class context eqns ; return (ClosedTypeFamily (Just eqns'), fvs) } @@ -1987,16 +1990,16 @@ rnInjectivityAnn :: LHsQTyVars GhcRn -- ^ Type variables declared in -> LInjectivityAnn GhcPs -- ^ Injectivity annotation -> RnM (LInjectivityAnn GhcRn) rnInjectivityAnn tvBndrs (L _ (TyVarSig _ resTv)) - (L srcSpan (InjectivityAnn injFrom injTo)) + (L srcSpan (InjectivityAnn x injFrom injTo)) = do - { (injDecl'@(L _ (InjectivityAnn injFrom' injTo')), noRnErrors) + { (injDecl'@(L _ (InjectivityAnn _ injFrom' injTo')), noRnErrors) <- askNoErrs $ bindLocalNames [hsLTyVarName resTv] $ -- The return type variable scopes over the injectivity annotation -- e.g. type family F a = (r::*) | r -> a do { injFrom' <- rnLTyVar injFrom ; injTo' <- mapM rnLTyVar injTo - ; return $ L srcSpan (InjectivityAnn injFrom' injTo') } + ; return $ L srcSpan (InjectivityAnn x injFrom' injTo') } ; let tvNames = Set.fromList $ hsAllLTyVarNames tvBndrs resName = hsLTyVarName resTv @@ -2032,12 +2035,12 @@ rnInjectivityAnn tvBndrs (L _ (TyVarSig _ resTv)) -- -- So we rename injectivity annotation like we normally would except that -- this time we expect "result" to be reported not in scope by rnLTyVar. -rnInjectivityAnn _ _ (L srcSpan (InjectivityAnn injFrom injTo)) = +rnInjectivityAnn _ _ (L srcSpan (InjectivityAnn x injFrom injTo)) = setSrcSpan srcSpan $ do (injDecl', _) <- askNoErrs $ do injFrom' <- rnLTyVar injFrom injTo' <- mapM rnLTyVar injTo - return $ L srcSpan (InjectivityAnn injFrom' injTo') + return $ L srcSpan (InjectivityAnn x injFrom' injTo') return $ injDecl' {- ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -773,7 +773,7 @@ findGlobalRdrEnv hsc_env imports (err : _, _) -> Left err } where idecls :: [LImportDecl GhcPs] - idecls = [noLoc d | IIDecl d <- imports] + idecls = [noLocA d | IIDecl d <- imports] imods :: [ModuleName] imods = [m | IIModule m <- imports] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -124,6 +124,9 @@ setL loc = CvtM (\_ _ -> Right (loc, ())) returnL :: a -> CvtM (Located a) returnL x = CvtM (\_ loc -> Right (loc, L loc x)) +returnLA :: a -> CvtM (LocatedA a) +returnLA x = CvtM (\_ loc -> Right (loc, L (noAnnSrcSpan loc) x)) + returnJustL :: a -> CvtM (Maybe (Located a)) returnJustL = fmap Just . returnL @@ -293,7 +296,8 @@ cvtDec (InstanceD o ctxt ty decs) , cid_binds = binds' , cid_sigs = Hs.mkClassOpSigs sigs' , cid_tyfam_insts = ats', cid_datafam_insts = adts' - , cid_overlap_mode = fmap (L loc . overlap) o } } + , cid_overlap_mode + = fmap (L (noAnnSrcSpan loc) . overlap) o } } where overlap pragma = case pragma of @@ -329,7 +333,7 @@ cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) ; returnJustL $ InstD noExtField $ DataFamInstD { dfid_ext = noAnn , dfid_inst = DataFamInstDecl { dfid_eqn = mkHsImplicitBndrs $ - FamEqn { feqn_ext = noExtField + FamEqn { feqn_ext = noAnn , feqn_tycon = tc' , feqn_bndrs = bndrs' , feqn_pats = typats' @@ -349,7 +353,7 @@ cvtDec (NewtypeInstD ctxt bndrs tys ksig constr derivs) ; returnJustL $ InstD noExtField $ DataFamInstD { dfid_ext = noAnn , dfid_inst = DataFamInstDecl { dfid_eqn = mkHsImplicitBndrs $ - FamEqn { feqn_ext = noExtField + FamEqn { feqn_ext = noAnn , feqn_tycon = tc' , feqn_bndrs = bndrs' , feqn_pats = typats' @@ -440,8 +444,8 @@ cvtTySynEqn (TySynEqn mb_bndrs lhs rhs) ConT nm -> do { nm' <- tconNameL nm ; rhs' <- cvtType rhs ; let args' = map wrap_tyarg args - ; returnL $ mkHsImplicitBndrs - $ FamEqn { feqn_ext = noExtField + ; returnLA $ mkHsImplicitBndrs + $ FamEqn { feqn_ext = noAnn , feqn_tycon = nm' , feqn_bndrs = mb_bndrs' , feqn_pats = args' @@ -450,8 +454,8 @@ cvtTySynEqn (TySynEqn mb_bndrs lhs rhs) InfixT t1 nm t2 -> do { nm' <- tconNameL nm ; args' <- mapM cvtType [t1,t2] ; rhs' <- cvtType rhs - ; returnL $ mkHsImplicitBndrs - $ FamEqn { feqn_ext = noExtField + ; returnLA $ mkHsImplicitBndrs + $ FamEqn { feqn_ext = noAnn , feqn_tycon = nm' , feqn_bndrs = mb_bndrs' , feqn_pats = @@ -697,7 +701,7 @@ cvtForD (ImportF callconv safety from nm ty) mk_imp impspec = do { nm' <- vNameL nm ; ty' <- cvtType ty - ; return (ForeignImport { fd_i_ext = noExtField + ; return (ForeignImport { fd_i_ext = noAnn , fd_name = nm' , fd_sig_ty = mkLHsSigType ty' , fd_fi = impspec }) @@ -714,7 +718,7 @@ cvtForD (ExportF callconv as nm ty) (mkFastString as) (cvt_conv callconv))) (noLoc (SourceText as)) - ; return $ ForeignExport { fd_e_ext = noExtField + ; return $ ForeignExport { fd_e_ext = noAnn , fd_name = nm' , fd_sig_ty = mkLHsSigType ty' , fd_fe = e } } @@ -777,8 +781,8 @@ cvtPragmaD (RuleP nm ty_bndrs tm_bndrs lhs rhs phases) ; returnJustL $ Hs.RuleD noExtField $ HsRules { rds_ext = noAnn , rds_src = SourceText "{-# RULES" - , rds_rules = [noLoc $ - HsRule { rd_ext = noExtField + , rds_rules = [noLocA $ + HsRule { rd_ext = noAnn , rd_name = (noLoc (quotedSourceText nm,nm')) , rd_act = act , rd_tyvs = ty_bndrs' @@ -1688,7 +1692,7 @@ cvtInjectivityAnnotation :: TH.InjectivityAnn cvtInjectivityAnnotation (TH.InjectivityAnn annLHS annRHS) = do { annLHS' <- tNameL annLHS ; annRHS' <- mapM tNameL annRHS - ; returnL (Hs.InjectivityAnn annLHS' annRHS') } + ; returnL (Hs.InjectivityAnn noAnn annLHS' annRHS') } cvtPatSynSigTy :: TH.Type -> CvtM (LHsType GhcPs) -- pattern synonym types are of peculiar shapes, which is why we treat ===================================== compiler/main/HeaderInfo.hs ===================================== @@ -125,18 +125,19 @@ mkPrelImports this_mod loc implicit_prelude import_decls <- import_decls , unLoc mod == pRELUDE_NAME ] + loc' = noAnnSrcSpan loc preludeImportDecl :: LImportDecl GhcPs preludeImportDecl - = L loc $ ImportDecl { ideclExt = noAnn, - ideclSourceSrc = NoSourceText, - ideclName = L loc pRELUDE_NAME, - ideclPkgQual = Nothing, - ideclSource = False, - ideclSafe = False, -- Not a safe import - ideclQualified = NotQualified, - ideclImplicit = True, -- Implicit! - ideclAs = Nothing, - ideclHiding = Nothing } + = L loc' $ ImportDecl { ideclExt = noAnn, + ideclSourceSrc = NoSourceText, + ideclName = L loc pRELUDE_NAME, + ideclPkgQual = Nothing, + ideclSource = False, + ideclSafe = False, -- Not a safe import + ideclQualified = NotQualified, + ideclImplicit = True, -- Implicit! + ideclAs = Nothing, + ideclHiding = Nothing } -------------------------------------------------------------- -- Get options ===================================== compiler/main/HscStats.hs ===================================== @@ -22,7 +22,7 @@ import Data.Char -- | Source Statistics ppSourceStats :: Bool -> Located HsModule -> SDoc -ppSourceStats short (L _ (HsModule _ exports imports ldecls _ _)) +ppSourceStats short (L _ (HsModule _ _ exports imports ldecls _ _)) = (if short then hcat else vcat) (map pp_val [("ExportAll ", export_all), -- 1 if no export list ===================================== compiler/parser/Lexer.x ===================================== @@ -2124,7 +2124,7 @@ data PState = PState { -- locations of 'noise' tokens in the source, so that users of -- the GHC API can do source to source conversions. -- See note [Api annotations] in ApiAnnotation.hs - annotations :: [(ApiAnnKey,[RealSrcSpan])], + -- AZ annotations :: [(ApiAnnKey,[RealSrcSpan])], eof_pos :: Maybe RealSrcSpan, comment_q :: [RealLocated AnnotationComment], annotations_comments :: [(RealSrcSpan,[RealLocated AnnotationComment])] @@ -2606,7 +2606,7 @@ mkPStatePure options buf loc = alr_context = [], alr_expecting_ocurly = Nothing, alr_justClosedExplicitLetBlock = False, - annotations = [], + -- AZ annotations = [], eof_pos = Nothing, comment_q = [], annotations_comments = [] @@ -2692,7 +2692,7 @@ instance MonadP P where getBit ext = P $ \s -> let b = ext `xtest` pExtsBitmap (options s) in b `seq` POk s b addAnnotation (RealSrcSpan l _) a (RealSrcSpan v _) = do - addAnnotationOnly l a v + -- AZ addAnnotationOnly l a v _ <- allocateCommentsP l return () addAnnotation _ _ _ = return () @@ -3236,10 +3236,12 @@ data AddApiAnn = AddApiAnn AnnKeywordId SrcSpan deriving (Data,Show,Eq) instance Outputable AddApiAnn where ppr (AddApiAnn kw ss) = text "AddApiAnn" <+> ppr kw <+> ppr ss +{- AZ addAnnotationOnly :: RealSrcSpan -> AnnKeywordId -> RealSrcSpan -> P () addAnnotationOnly l a v = P $ \s -> POk s { annotations = ((l,a), [v]) : annotations s } () +-} -- |Given a 'SrcSpan' that surrounds a 'HsPar' or 'HsParTy', generate -- 'AddApiAnn' values for the opening and closing bordering on the start ===================================== compiler/parser/Parser.y ===================================== @@ -725,12 +725,12 @@ unitdecl :: { LHsUnitDecl PackageName } False -> HsSrcFile True -> HsBootFile) $4 - (Just $ sL1 $2 (HsModule (Just $4) $6 (fst $ snd $8) (snd $ snd $8) $5 $1)) } + (Just $ sL1 $2 (HsModule noAnn (Just $4) $6 (fst $ snd $8) (snd $ snd $8) $5 $1)) } | maybedocheader 'signature' modid maybemodwarning maybeexports 'where' body { sL1 $2 $ DeclD HsigFile $3 - (Just $ sL1 $2 (HsModule (Just $3) $5 (fst $ snd $7) (snd $ snd $7) $4 $1)) } + (Just $ sL1 $2 (HsModule noAnn (Just $3) $5 (fst $ snd $7) (snd $ snd $7) $4 $1)) } -- NB: MUST have maybedocheader here, otherwise shift-reduce conflict -- will prevent us from parsing both forms. | maybedocheader 'module' maybe_src modid @@ -761,23 +761,20 @@ unitdecl :: { LHsUnitDecl PackageName } signature :: { Located HsModule } : maybedocheader 'signature' modid maybemodwarning maybeexports 'where' body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 (fst $ snd $7) - (snd $ snd $7) $4 $1) - ) - ([mj AnnSignature $2, mj AnnWhere $6] ++ fst $7) } + acs (\cs -> L loc (HsModule (ApiAnn ([mj AnnSignature $2, mj AnnWhere $6] ++ fst $7) cs) + (Just $3) $5 (fst $ snd $7) + (snd $ snd $7) $4 $1) )} module :: { Located HsModule } : maybedocheader 'module' modid maybemodwarning maybeexports 'where' body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 (fst $ snd $7) - (snd $ snd $7) $4 $1) - ) - ([mj AnnModule $2, mj AnnWhere $6] ++ fst $7) } + acs (\cs -> L loc (HsModule (ApiAnn ([mj AnnModule $2, mj AnnWhere $6] ++ fst $7) cs) + (Just $3) $5 (fst $ snd $7) + (snd $ snd $7) $4 $1) ) } | body2 {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule Nothing Nothing - (fst $ snd $1) (snd $ snd $1) Nothing Nothing)) - (fst $1) } + acs (\cs -> L loc (HsModule (ApiAnn (fst $1) cs) Nothing Nothing + (fst $ snd $1) (snd $ snd $1) Nothing Nothing)) } maybedocheader :: { Maybe LHsDocString } : moduleheader { $1 } @@ -789,13 +786,13 @@ missing_module_keyword :: { () } implicit_top :: { () } : {- empty -} {% pushModuleContext } -maybemodwarning :: { Maybe (Located WarningTxt) } +maybemodwarning :: { Maybe (LocatedA WarningTxt) } : '{-# DEPRECATED' strings '#-}' - {% ajs (\_ -> sLL $1 $> $ DeprecatedTxt (sL1 $1 (getDEPRECATED_PRAGs $1)) (snd $ unLoc $2)) - (mo $1:mc $3: (fst $ unLoc $2)) } + {% fmap Just $ amsr (sLL $1 $> $ DeprecatedTxt (sL1 $1 (getDEPRECATED_PRAGs $1)) (snd $ unLoc $2)) + (mo $1:mc $3: (fst $ unLoc $2))} | '{-# WARNING' strings '#-}' - {% ajs (\_ -> sLL $1 $> $ WarningTxt (sL1 $1 (getWARNING_PRAGs $1)) (snd $ unLoc $2)) - (mo $1:mc $3 : (fst $ unLoc $2)) } + {% fmap Just $ amsr (sLL $1 $> $ WarningTxt (sL1 $1 (getWARNING_PRAGs $1)) (snd $ unLoc $2)) + (mo $1:mc $3 : (fst $ unLoc $2))} | {- empty -} { Nothing } body :: { ([AddApiAnn] @@ -826,15 +823,17 @@ top1 :: { ([LImportDecl GhcPs], [LHsDecl GhcPs]) } header :: { Located HsModule } : maybedocheader 'module' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 $7 [] $4 $1 - )) [mj AnnModule $2,mj AnnWhere $6] } + acs (\cs -> L loc (HsModule (ApiAnn [mj AnnModule $2,mj AnnWhere $6] cs) + (Just $3) $5 $7 [] $4 $1 + )) } | maybedocheader 'signature' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 $7 [] $4 $1 - )) [mj AnnModule $2,mj AnnWhere $6] } + acs (\cs -> L loc (HsModule (ApiAnn [mj AnnModule $2,mj AnnWhere $6] cs) + (Just $3) $5 $7 [] $4 $1 + )) } | header_body2 {% fileSrcSpan >>= \ loc -> - return (L loc (HsModule Nothing Nothing $1 [] Nothing + return (L loc (HsModule noAnn Nothing Nothing $1 [] Nothing Nothing)) } header_body :: { [LImportDecl GhcPs] } @@ -855,21 +854,28 @@ header_top_importdecls :: { [LImportDecl GhcPs] } ----------------------------------------------------------------------------- -- The Export List -maybeexports :: { (Maybe (Located [LIE GhcPs])) } - : '(' exportlist ')' {% amsL (comb2 $1 $>) [mop $1,mcp $3] >> - return (Just (sLL $1 $> (fromOL $2))) } +maybeexports :: { (Maybe (LocatedA [LIE GhcPs])) } + : '(' exportlist ')' {% fmap Just $ amsr (sLL $1 $> (fromOL $2)) [mop $1,mcp $3] } | {- empty -} { Nothing } exportlist :: { OrdList (LIE GhcPs) } - : expdoclist ',' expdoclist {% addAnnotation (oll $1) AnnComma (gl $2) - >> return ($1 `appOL` $3) } + : expdoclist ',' expdoclist {% if isNilOL $1 + then return ($1 `appOL` $3) + else case unsnocOL $1 of + (hs,t) -> do + t' <- addAnnotationA t AnnComma (gl $2) + return (snocOL hs t' `appOL` $3) } | exportlist1 { $1 } exportlist1 :: { OrdList (LIE GhcPs) } : expdoclist export expdoclist ',' exportlist1 - {% (addAnnotation (oll ($1 `appOL` $2 `appOL` $3)) - AnnComma (gl $4) ) >> - return ($1 `appOL` $2 `appOL` $3 `appOL` $5) } + {% let ls = $1 `appOL` $2 `appOL` $3 + in if isNilOL ls + then return (ls `appOL` $5) + else case unsnocOL ls of + (hs, t) -> do + t' <- addAnnotationA t AnnComma (gl $4) + return (snocOL hs t' `appOL` $5)} | expdoclist export expdoclist { $1 `appOL` $2 `appOL` $3 } | expdoclist { $1 } @@ -878,20 +884,19 @@ expdoclist :: { OrdList (LIE GhcPs) } | {- empty -} { nilOL } exp_doc :: { OrdList (LIE GhcPs) } - : docsection { unitOL (sL1 $1 (case (unLoc $1) of (n, doc) -> IEGroup noExtField n doc)) } - | docnamed { unitOL (sL1 $1 (IEDocNamed noExtField ((fst . unLoc) $1))) } - | docnext { unitOL (sL1 $1 (IEDoc noExtField (unLoc $1))) } - + : docsection { unitOL (sL1a $1 (case (unLoc $1) of (n, doc) -> IEGroup noExtField n doc)) } + | docnamed { unitOL (sL1a $1 (IEDocNamed noExtField ((fst . unLoc) $1))) } + | docnext { unitOL (sL1a $1 (IEDoc noExtField (unLoc $1))) } -- No longer allow things like [] and (,,,) to be exported -- They are built in syntax, always available export :: { OrdList (LIE GhcPs) } : qcname_ext export_subspec {% mkModuleImpExp $1 (snd $ unLoc $2) - >>= \ie -> amsu (\_ -> sLL $1 $> ie) (fst $ unLoc $2) } - | 'module' modid {% amsu (\cs -> sLL $1 $> (IEModuleContents (ApiAnn [mj AnnModule $1] cs) $2)) - [mj AnnModule $1] } - | 'pattern' qcon {% amsu (\cs -> sLLlA $1 $> (IEVar (ApiAnn [mj AnnPattern $1] cs) (sLLlA $1 $> (IEPattern $2)))) - [mj AnnPattern $1] } + >>= \ie -> fmap unitOL (amsr (sLL $1 $> ie) (fst $ unLoc $2)) } + | 'module' modid {% fmap (unitOL . reLocA) (ams (\cs -> sLL $1 $> (IEModuleContents (ApiAnn [mj AnnModule $1] cs) $2)) + [mj AnnModule $1]) } + | 'pattern' qcon {% fmap (unitOL . reLocA) (ams (\cs -> sLLlA $1 $> (IEVar (ApiAnn [mj AnnPattern $1] cs) (sLLlA $1 $> (IEPattern $2)))) + [mj AnnPattern $1]) } export_subspec :: { Located ([AddApiAnn],ImpExpSubSpec) } : {- empty -} { sL0 ([],ImpExpAbs) } @@ -925,9 +930,9 @@ qcname_ext_w_wildcard :: { Located ([AddApiAnn], Located ImpExpQcSpec) } qcname_ext :: { Located ImpExpQcSpec } : qcname { sL1A $1 (ImpExpQcName $1) } - | 'type' oqtycon {% do { n <- mkTypeImpExp $2 - ; ams (\_ -> sLLlA $1 $> (ImpExpQcType n)) - [mj AnnType $1] } } + | 'type' oqtycon {% do { n' <- reA $1 $2 [mj AnnType $1] + ; n <- mkTypeImpExp n' + ; return $ sLLlA $1 $> (ImpExpQcType n) }} qcname :: { LocatedA RdrName } -- Variable or type constructor : qvar { $1 } -- Things which look like functions @@ -961,7 +966,7 @@ importdecls importdecls_semi :: { [LImportDecl GhcPs] } importdecls_semi : importdecls_semi importdecl semis1 - {% ams (\_ -> $2) $3 >> return ($2 : $1) } + {% amsA $2 $3 >> return ($2 : $1) } | {- empty -} { [] } importdecl :: { LImportDecl GhcPs } @@ -971,8 +976,7 @@ importdecl :: { LImportDecl GhcPs } ; let anns = (mj AnnImport $1 : fst (fst $2) ++ fst $3 ++ fmap (mj AnnQualified) (maybeToList $4) ++ fst $5 ++ fmap (mj AnnQualified) (maybeToList $7) ++ fst $8) - ; cs <- allocateCommentsS (comb4 $1 $6 (snd $8) $9) - ; ams (\_ -> L (comb4 $1 $6 (snd $8) $9) $ + ; fmap reLocA $ ams (\cs -> L (comb4 $1 $6 (snd $8) $9) $ ImportDecl { ideclExt = ApiAnn anns cs , ideclSourceSrc = snd $ fst $2 , ideclName = $6, ideclPkgQual = snd $5 @@ -1014,20 +1018,20 @@ maybeas :: { ([AddApiAnn],Located (Maybe (Located ModuleName))) } ,sLL $1 $> (Just $2)) } | {- empty -} { ([],noLoc Nothing) } -maybeimpspec :: { Located (Maybe (Bool, Located [LIE GhcPs])) } +maybeimpspec :: { Located (Maybe (Bool, LocatedA [LIE GhcPs])) } : impspec {% let (b, ie) = unLoc $1 in checkImportSpec ie >>= \checkedIe -> return (L (gl $1) (Just (b, checkedIe))) } | {- empty -} { noLoc Nothing } -impspec :: { Located (Bool, Located [LIE GhcPs]) } - : '(' exportlist ')' {% ams (\_ -> sLL $1 $> (False, - sLL $1 $> $ fromOL $2)) - [mop $1,mcp $3] } - | 'hiding' '(' exportlist ')' {% ams (\_ -> sLL $1 $> (True, - sLL $1 $> $ fromOL $3)) - [mj AnnHiding $1,mop $2,mcp $4] } +impspec :: { Located (Bool, LocatedA [LIE GhcPs]) } + : '(' exportlist ')' {% do { es <- amsr (sLL $1 $> $ fromOL $2) + [mop $1,mcp $3] + ; return $ sLL $1 $> (False, es)} } + | 'hiding' '(' exportlist ')' {% do { es <- amsr (sLL $1 $> $ fromOL $3) + [mj AnnHiding $1,mop $2,mcp $4] + ; return $ sLL $1 $> (True, es)} } ----------------------------------------------------------------------------- -- Fixity Declarations @@ -1043,8 +1047,10 @@ infix :: { Located FixityDirection } | 'infixr' { sL1 $1 InfixR } ops :: { Located (OrdList (LocatedA RdrName)) } - : ops ',' op {% addAnnotation (ollA $ unLoc $1) AnnComma (gl $2) >> - return (sLLlA $1 $> ((unLoc $1) `appOL` unitOL $3))} + : ops ',' op {% case unsnocOL (unLoc $1) of + (hs,t) -> do + t' <- addAnnotationA t AnnComma (gl $2) + return (sLLlA $1 $> (snocOL hs t' `appOL` unitOL $3)) } | op { sL1A $1 (unitOL $1) } ----------------------------------------------------------------------------- @@ -1056,7 +1062,7 @@ topdecls :: { OrdList (LHsDecl GhcPs) } -- May have trailing semicolons, can be empty topdecls_semi :: { OrdList (LHsDecl GhcPs) } - : topdecls_semi topdecl semis1 {% ams (\_ -> $2) $3 >> return ($1 `snocOL` $2) } + : topdecls_semi topdecl semis1 {% amsr $2 $3 >> return ($1 `snocOL` $2) } | {- empty -} { nilOL } topdecl :: { LHsDecl GhcPs } @@ -1066,17 +1072,12 @@ topdecl :: { LHsDecl GhcPs } | inst_decl { sL1 $1 (InstD noExtField (unLoc $1)) } | stand_alone_deriving { sLL $1 $> (DerivD noExtField (unLoc $1)) } | role_annot { sL1 $1 (RoleAnnotD noExtField (unLoc $1)) } - | 'default' '(' comma_types0 ')' {% ams (\cs -> sLL $1 $> (DefD noExtField (DefaultDecl (ApiAnn [mj AnnDefault $1,mop $2,mcp $4] cs) $3))) - [mj AnnDefault $1 - ,mop $2,mcp $4] } - | 'foreign' fdecl {% ams (\_ -> sLL $1 $> (snd $ unLoc $2)) - (mj AnnForeign $1:(fst $ unLoc $2)) } - | '{-# DEPRECATED' deprecations '#-}' {% ams (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getDEPRECATED_PRAGs $1) (fromOL $2))) - [mo $1,mc $3] } - | '{-# WARNING' warnings '#-}' {% ams (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getWARNING_PRAGs $1) (fromOL $2))) - [mo $1,mc $3] } - | '{-# RULES' rules '#-}' {% ams (\cs -> sLL $1 $> $ RuleD noExtField (HsRules (ApiAnn [mo $1,mc $3] cs) (getRULES_PRAGs $1) (fromOL $2))) - [mo $1,mc $3] } + | 'default' '(' comma_types0 ')' {% acs (\cs -> sLL $1 $> + (DefD noExtField (DefaultDecl (ApiAnn [mj AnnDefault $1,mop $2,mcp $4] cs) $3))) } + | 'foreign' fdecl {% acs (\cs -> sLL $1 $> ((snd $ unLoc $2) (ApiAnn (mj AnnForeign $1:(fst $ unLoc $2)) cs))) } + | '{-# DEPRECATED' deprecations '#-}' {% acs (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getDEPRECATED_PRAGs $1) (fromOL $2))) } + | '{-# WARNING' warnings '#-}' {% acs (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getWARNING_PRAGs $1) (fromOL $2))) } + | '{-# RULES' rules '#-}' {% acs (\cs -> sLL $1 $> $ RuleD noExtField (HsRules (ApiAnn [mo $1,mc $3] cs) (getRULES_PRAGs $1) (reverse $2))) } | annotation { $1 } | decl_no_th { $1 } @@ -1091,8 +1092,7 @@ topdecl :: { LHsDecl GhcPs } -- cl_decl :: { LTyClDecl GhcPs } : 'class' tycl_hdr fds where_cls - {% amms (mkClassDecl (comb4 $1 $2 $3 $4) $2 $3 (snd $ unLoc $4) - (ApiAnn (mj AnnClass $1:(fst $ unLoc $3)++(fst $ unLoc $4)) noCom)) + {% mkClassDecl (comb4 $1 $2 $3 $4) $2 $3 (snd $ unLoc $4) (mj AnnClass $1:(fst $ unLoc $3)++(fst $ unLoc $4)) } -- Type declarations (toplevel) @@ -1107,63 +1107,59 @@ ty_decl :: { LTyClDecl GhcPs } -- -- Note the use of type for the head; this allows -- infix type constructors to be declared - {% amms (mkTySynonym (comb2 $1 $4) $2 $4 - (ApiAnn [mj AnnType $1,mj AnnEqual $3] noCom)) - [mj AnnType $1,mj AnnEqual $3] } + {% mkTySynonym (comb2 $1 $4) $2 $4 [mj AnnType $1,mj AnnEqual $3] } -- type family declarations | 'type' 'family' type opt_tyfam_kind_sig opt_injective_info where_type_family -- Note the use of type for the head; this allows -- infix type constructors to be declared - {% amms (mkFamDecl (comb4 $1 $3 $4 $5) (snd $ unLoc $6) $3 + {% mkFamDecl (comb4 $1 $3 $4 $5) (snd $ unLoc $6) $3 (snd $ unLoc $4) (snd $ unLoc $5) - (ApiAnn (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4) - ++ (fst $ unLoc $5) ++ (fst $ unLoc $6)) noCom)) - (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4) - ++ (fst $ unLoc $5) ++ (fst $ unLoc $6)) } + (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4) + ++ (fst $ unLoc $5) ++ (fst $ unLoc $6)) } -- ordinary data type or newtype declaration | data_or_newtype capi_ctype tycl_hdr constrs maybe_derivings - {% amms (mkTyData (comb4 $1 $3 $4 $5) (snd $ unLoc $1) $2 $3 + {% mkTyData (comb4 $1 $3 $4 $5) (snd $ unLoc $1) $2 $3 Nothing (reverse (snd $ unLoc $4)) (fmap reverse $5) - (ApiAnn ((fst $ unLoc $1):(fst $ unLoc $4)) noCom)) + ((fst $ unLoc $1):(fst $ unLoc $4)) } -- We need the location on tycl_hdr in case -- constrs and deriving are both empty - ((fst $ unLoc $1):(fst $ unLoc $4)) } -- ordinary GADT declaration | data_or_newtype capi_ctype tycl_hdr opt_kind_sig gadt_constrlist maybe_derivings - {% amms (mkTyData (comb4 $1 $3 $5 $6) (snd $ unLoc $1) $2 $3 + {% mkTyData (comb4 $1 $3 $5 $6) (snd $ unLoc $1) $2 $3 (snd $ unLoc $4) (snd $ unLoc $5) (fmap reverse $6) - (ApiAnn ((fst $ unLoc $1):(fst $ unLoc $4)++(fst $ unLoc $5)) noCom)) + ((fst $ unLoc $1):(fst $ unLoc $4)++(fst $ unLoc $5)) } -- We need the location on tycl_hdr in case -- constrs and deriving are both empty - ((fst $ unLoc $1):(fst $ unLoc $4)++(fst $ unLoc $5)) } -- data/newtype family | 'data' 'family' type opt_datafam_kind_sig - {% amms (mkFamDecl (comb3 $1 $2 $4) DataFamily $3 + {% mkFamDecl (comb3 $1 $2 $4) DataFamily $3 (snd $ unLoc $4) Nothing - (ApiAnn (mj AnnData $1:mj AnnFamily $2:(fst $ unLoc $4)) noCom)) - (mj AnnData $1:mj AnnFamily $2:(fst $ unLoc $4)) } + (mj AnnData $1:mj AnnFamily $2:(fst $ unLoc $4)) } -- standalone kind signature standalone_kind_sig :: { LStandaloneKindSig GhcPs } : 'type' sks_vars '::' ktypedoc - {% amms (mkStandaloneKindSig (comb2 $1 $4) $2 $4 - (ApiAnn [mj AnnType $1,mu AnnDcolon $3] noCom)) - [mj AnnType $1,mu AnnDcolon $3] } + {% mkStandaloneKindSig (comb2 $1 $4) $2 $4 + [mj AnnType $1,mu AnnDcolon $3]} -- See also: sig_vars sks_vars :: { Located [LocatedA RdrName] } -- Returned in reverse order : sks_vars ',' oqtycon - {% addAnnotation (glA $ head $ unLoc $1) AnnComma (gl $2) >> - return (sLLlA $1 $> ($3 : unLoc $1)) } + -- {% addAnnotation (glA $ head $ unLoc $1) AnnComma (gl $2) >> + -- return (sLLlA $1 $> ($3 : unLoc $1)) } + {% case unLoc $1 of + (h:t) -> do + h' <- addAnnotationA h AnnComma (gl $2) + return (sLLlA $1 $> ($3 : h' : t)) } | oqtycon { sL1A $1 [$1] } inst_decl :: { LInstDecl GhcPs } @@ -1177,68 +1173,57 @@ inst_decl :: { LInstDecl GhcPs } , cid_tyfam_insts = ats , cid_overlap_mode = $2 , cid_datafam_insts = adts } - ; ams (\cs -> L (comb3 $1 (hsSigType $3) $4) (ClsInstD { cid_d_ext = noExtField, cid_inst = cid cs })) - anns } } + ; acs (\cs -> L (comb3 $1 (hsSigType $3) $4) + (ClsInstD { cid_d_ext = noExtField, cid_inst = cid cs })) + } } -- type instance declarations | 'type' 'instance' ty_fam_inst_eqn - {% ams (\_ -> $3) (fst $ unLoc $3) - >> amms (mkTyFamInst (comb2 $1 $3) (snd $ unLoc $3) - (ApiAnn (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) noCom)) - (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) } + {% mkTyFamInst (comb2A $1 $3) (unLoc $3) + (mj AnnType $1:mj AnnInstance $2:[]) } -- data/newtype instance declaration | data_or_newtype 'instance' capi_ctype tycl_hdr_inst constrs maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) + {% mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) Nothing (reverse (snd $ unLoc $5)) (fmap reverse $6) - (ApiAnn ((fst $ unLoc $1):mj AnnInstance $2:(fst $ unLoc $4)++(fst $ unLoc $5)) noCom)) - ((fst $ unLoc $1):mj AnnInstance $2:(fst $ unLoc $4)++(fst $ unLoc $5)) } + ((fst $ unLoc $1):mj AnnInstance $2:(fst $ unLoc $4)++(fst $ unLoc $5)) } -- GADT instance declaration | data_or_newtype 'instance' capi_ctype tycl_hdr_inst opt_kind_sig gadt_constrlist maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 (snd $ unLoc $4) + {% mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 (snd $ unLoc $4) (snd $ unLoc $5) (snd $ unLoc $6) (fmap reverse $7) - (ApiAnn ((fst $ unLoc $1):mj AnnInstance $2 - :(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) noCom)) - ((fst $ unLoc $1):mj AnnInstance $2 + ((fst $ unLoc $1):mj AnnInstance $2 :(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) } -overlap_pragma :: { Maybe (Located OverlapMode) } - : '{-# OVERLAPPABLE' '#-}' {% ajs (\_ -> sLL $1 $> (Overlappable (getOVERLAPPABLE_PRAGs $1))) +overlap_pragma :: { Maybe (LocatedA OverlapMode) } + : '{-# OVERLAPPABLE' '#-}' {% fmap Just $ amsr (sLL $1 $> (Overlappable (getOVERLAPPABLE_PRAGs $1))) [mo $1,mc $2] } - | '{-# OVERLAPPING' '#-}' {% ajs (\_ -> sLL $1 $> (Overlapping (getOVERLAPPING_PRAGs $1))) + | '{-# OVERLAPPING' '#-}' {% fmap Just $ amsr (sLL $1 $> (Overlapping (getOVERLAPPING_PRAGs $1))) [mo $1,mc $2] } - | '{-# OVERLAPS' '#-}' {% ajs (\_ -> sLL $1 $> (Overlaps (getOVERLAPS_PRAGs $1))) + | '{-# OVERLAPS' '#-}' {% fmap Just $ amsr (sLL $1 $> (Overlaps (getOVERLAPS_PRAGs $1))) [mo $1,mc $2] } - | '{-# INCOHERENT' '#-}' {% ajs (\_ -> sLL $1 $> (Incoherent (getINCOHERENT_PRAGs $1))) + | '{-# INCOHERENT' '#-}' {% fmap Just $ amsr (sLL $1 $> (Incoherent (getINCOHERENT_PRAGs $1))) [mo $1,mc $2] } | {- empty -} { Nothing } deriv_strategy_no_via :: { LDerivStrategy GhcPs } - : 'stock' {% ams (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) - [mj AnnStock $1] } - | 'anyclass' {% ams (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) - [mj AnnAnyclass $1] } - | 'newtype' {% ams (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) - [mj AnnNewtype $1] } + : 'stock' {% acs (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) } + | 'anyclass' {% acs (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) } + | 'newtype' {% acs (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) } deriv_strategy_via :: { LDerivStrategy GhcPs } - : 'via' type {% ams (\cs -> sLL $1 $> (ViaStrategy (XViaStrategyPs (ApiAnn [mj AnnVia $1] cs) - (mkLHsSigType $2)))) - [mj AnnVia $1] } + : 'via' type {% acs (\cs -> sLL $1 $> (ViaStrategy (XViaStrategyPs (ApiAnn [mj AnnVia $1] cs) + (mkLHsSigType $2)))) } deriv_standalone_strategy :: { Maybe (LDerivStrategy GhcPs) } - : 'stock' {% ajs (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) - [mj AnnStock $1] } - | 'anyclass' {% ajs (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) - [mj AnnAnyclass $1] } - | 'newtype' {% ajs (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) - [mj AnnNewtype $1] } + : 'stock' {% fmap Just $ acs (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) } + | 'anyclass' {% fmap Just $ acs (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) } + | 'newtype' {% fmap Just $ acs (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) } | deriv_strategy_via { Just $1 } | {- empty -} { Nothing } @@ -1251,8 +1236,7 @@ opt_injective_info :: { Located ([AddApiAnn], Maybe (LInjectivityAnn GhcPs)) } injectivity_cond :: { LInjectivityAnn GhcPs } : tyvarid '->' inj_varids - {% ams (\_ -> sLLAl $1 $> (InjectivityAnn $1 (reverse (unLoc $3)))) - [mu AnnRarrow $2] } + {% acs (\cs -> sLLAl $1 $> (InjectivityAnn (ApiAnn [mu AnnRarrow $2] cs) $1 (reverse (unLoc $3)))) } inj_varids :: { Located [LocatedA RdrName] } : inj_varids tyvarid { sLLlA $1 $> ($2 : unLoc $1) } @@ -1278,28 +1262,32 @@ ty_fam_inst_eqn_list :: { Located ([AddApiAnn],Maybe [LTyFamInstEqn GhcPs]) } ty_fam_inst_eqns :: { Located [LTyFamInstEqn GhcPs] } : ty_fam_inst_eqns ';' ty_fam_inst_eqn - {% let (L loc (anns, eqn)) = $3 in - asl (unLoc $1) $2 (L loc eqn) - >> ams (\_ -> $3) anns - >> return (sLL $1 $> (L loc eqn : unLoc $1)) } - | ty_fam_inst_eqns ';' {% addAnnotation (gl $1) AnnSemi (gl $2) - >> return (sLL $1 $> (unLoc $1)) } - | ty_fam_inst_eqn {% let (L loc (anns, eqn)) = $1 in - ams (\_ -> $1) anns - >> return (sLL $1 $> [L loc eqn]) } + {% let (L loc eqn) = $3 in + case unLoc $1 of + [] -> return (sLLlA $1 $> (L loc eqn : unLoc $1)) + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return (sLLlA $1 $> ($3 : h' : t)) } + | ty_fam_inst_eqns ';' {% case unLoc $1 of + [] -> return (sLL $1 $> (unLoc $1)) + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return (sLL $1 $> (h':t)) } + | ty_fam_inst_eqn { sLLAA $1 $> [$1] } | {- empty -} { noLoc [] } -ty_fam_inst_eqn :: { Located ([AddApiAnn],TyFamInstEqn GhcPs) } +ty_fam_inst_eqn :: { LTyFamInstEqn GhcPs } : 'forall' tv_bndrs '.' type '=' ktype {% do { hintExplicitForall $1 - ; (eqn,ann) <- mkTyFamInstEqn (Just $2) $4 $6 - ; return (sLL $1 $> - (mu AnnForall $1:mj AnnDot $3:mj AnnEqual $5:ann,eqn)) } } + ; mkTyFamInstEqn (comb2 $1 $>) (Just $2) $4 $6 (mu AnnForall $1:mj AnnDot $3:mj AnnEqual $5:[]) }} | type '=' ktype - {% do { (eqn,ann) <- mkTyFamInstEqn Nothing $1 $3 - ; return (sLL $1 $> (mj AnnEqual $2:ann, eqn)) } } + -- {% do { (eqn,ann) <- mkTyFamInstEqn Nothing $1 $3 + -- ; return (sLL $1 $> (mj AnnEqual $2:ann, eqn)) } } + {% mkTyFamInstEqn (comb2 $1 $>) Nothing $1 $3 (mj AnnEqual $2:[]) } -- Note the use of type for the head; this allows -- infix type constructors and type patterns +-- AZ working above + -- Associated type family declarations -- @@ -1313,39 +1301,32 @@ ty_fam_inst_eqn :: { Located ([AddApiAnn],TyFamInstEqn GhcPs) } at_decl_cls :: { LHsDecl GhcPs } : -- data family declarations, with optional 'family' keyword 'data' opt_family type opt_datafam_kind_sig - {% amms (liftM mkTyClD (mkFamDecl (comb3 $1 $3 $4) DataFamily $3 + {% liftM mkTyClD (mkFamDecl (comb3 $1 $3 $4) DataFamily $3 (snd $ unLoc $4) Nothing - (ApiAnn (mj AnnData $1:$2++(fst $ unLoc $4)) noCom))) - (mj AnnData $1:$2++(fst $ unLoc $4)) } + (mj AnnData $1:$2++(fst $ unLoc $4))) } -- type family declarations, with optional 'family' keyword -- (can't use opt_instance because you get shift/reduce errors | 'type' type opt_at_kind_inj_sig - {% amms (liftM mkTyClD + {% liftM mkTyClD (mkFamDecl (comb3 $1 $2 $3) OpenTypeFamily $2 (fst . snd $ unLoc $3) (snd . snd $ unLoc $3) - (ApiAnn (mj AnnType $1:(fst $ unLoc $3)) noCom))) - (mj AnnType $1:(fst $ unLoc $3)) } + (mj AnnType $1:(fst $ unLoc $3)) )} | 'type' 'family' type opt_at_kind_inj_sig - {% amms (liftM mkTyClD + {% liftM mkTyClD (mkFamDecl (comb3 $1 $3 $4) OpenTypeFamily $3 (fst . snd $ unLoc $4) (snd . snd $ unLoc $4) - (ApiAnn (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4)) noCom))) - (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4)) } + (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4)))} -- default type instances, with optional 'instance' keyword | 'type' ty_fam_inst_eqn - {% ams (\_ -> $2) (fst $ unLoc $2) >> - amms (liftM mkInstD (mkTyFamInst (comb2 $1 $2) (snd $ unLoc $2) - (ApiAnn (mj AnnType $1:(fst $ unLoc $2)) noCom))) - (mj AnnType $1:(fst $ unLoc $2)) } + {% liftM mkInstD (mkTyFamInst (comb2A $1 $2) (unLoc $2) + [mj AnnType $1]) } | 'type' 'instance' ty_fam_inst_eqn - {% ams (\_ -> $3) (fst $ unLoc $3) >> - amms (liftM mkInstD (mkTyFamInst (comb2 $1 $3) (snd $ unLoc $3) - (ApiAnn (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) noCom))) - (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) } + {% liftM mkInstD (mkTyFamInst (comb2A $1 $3) (unLoc $3) + (mj AnnType $1:mj AnnInstance $2:[]) )} opt_family :: { [AddApiAnn] } : {- empty -} { [] } @@ -1362,27 +1343,23 @@ at_decl_inst :: { LInstDecl GhcPs } : 'type' opt_instance ty_fam_inst_eqn -- Note the use of type for the head; this allows -- infix type constructors and type patterns - {% ams (\_ -> $3) (fst $ unLoc $3) >> - amms (mkTyFamInst (comb2 $1 $3) (snd $ unLoc $3) - (ApiAnn (mj AnnType $1:$2++(fst $ unLoc $3)) noCom)) - (mj AnnType $1:$2++(fst $ unLoc $3)) } + {% mkTyFamInst (comb2A $1 $3) (unLoc $3) + (mj AnnType $1:$2) } -- data/newtype instance declaration, with optional 'instance' keyword | data_or_newtype opt_instance capi_ctype tycl_hdr_inst constrs maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) + {% mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) Nothing (reverse (snd $ unLoc $5)) (fmap reverse $6) - (ApiAnn ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)) noCom)) - ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)) } + ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)) } -- GADT instance declaration, with optional 'instance' keyword | data_or_newtype opt_instance capi_ctype tycl_hdr_inst opt_kind_sig gadt_constrlist maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 + {% mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 (snd $ unLoc $4) (snd $ unLoc $5) (snd $ unLoc $6) (fmap reverse $7) - (ApiAnn ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) noCom)) ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) } data_or_newtype :: { Located (AddApiAnn, NewOrData) } @@ -1684,24 +1661,30 @@ wherebinds :: { Located ([AddApiAnn],Located (HsLocalBinds GhcPs)) } ----------------------------------------------------------------------------- -- Transformation Rules -rules :: { OrdList (LRuleDecl GhcPs) } - : rules ';' rule {% addAnnotation (oll $1) AnnSemi (gl $2) - >> return ($1 `snocOL` $3) } - | rules ';' {% addAnnotation (oll $1) AnnSemi (gl $2) - >> return $1 } - | rule { unitOL $1 } - | {- empty -} { nilOL } +rules :: { [LRuleDecl GhcPs] } -- Reversed + : rules ';' rule {% case $1 of + [] -> return ($3:$1) + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return ($3:h':t) } + | rules ';' {% case $1 of + [] -> return $1 + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return (h':t) } + | rule { [$1] } + | {- empty -} { [] } rule :: { LRuleDecl GhcPs } : STRING rule_activation rule_foralls infixexp '=' exp {%runECP_P $4 >>= \ $4 -> runECP_P $6 >>= \ $6 -> - ams (\_ -> sLLlA $1 $> $ HsRule { rd_ext = noExtField + acsA (\cs -> sLLlA $1 $> $ HsRule + { rd_ext = ApiAnn (mj AnnEqual $5 : (fst $2) ++ (fstOf3 $3)) cs , rd_name = L (gl $1) (getSTRINGs $1, getSTRING $1) , rd_act = (snd $2) `orElse` AlwaysActive , rd_tyvs = sndOf3 $3, rd_tmvs = thdOf3 $3 - , rd_lhs = reLoc $4, rd_rhs = reLoc $6 }) - (mj AnnEqual $5 : (fst $2) ++ (fstOf3 $3)) } + , rd_lhs = reLoc $4, rd_rhs = reLoc $6 }) } -- Rules can be specified to be NeverActive, unlike inline/specialize pragmas rule_activation :: { ([AddApiAnn],Maybe Activation) } @@ -1844,7 +1827,7 @@ annotation :: { LHsDecl GhcPs } ----------------------------------------------------------------------------- -- Foreign import and export declarations -fdecl :: { Located ([AddApiAnn],HsDecl GhcPs) } +fdecl :: { Located ([AddApiAnn],ApiAnn -> HsDecl GhcPs) } fdecl : 'import' callconv safety fspec {% mkImport $2 $3 (snd $ unLoc $4) >>= \i -> return (sLL $1 $> (mj AnnImport $1 : (fst $ unLoc $4),i)) } @@ -4166,6 +4149,9 @@ ams a bs = do cs <- addAnnsAt l bs return (a cs) +acsA :: MonadP m => (ApiAnnComments -> Located a) -> m (LocatedA a) +acsA a = reLocA <$> acs a + acs :: MonadP m => (ApiAnnComments -> Located a) -> m (Located a) acs a = do let (L l _) = a [] @@ -4178,9 +4164,15 @@ acsExpr a = do { expr :: (LHsExpr GhcPs) <- runPV $ acs a amsA :: MonadP m => LocatedA a -> [AddApiAnn] -> m (LocatedA a) -amsA a@(L l _) bs = do +amsA (L l a) bs = do cs <- addAnnsAt (locA l) bs - return a + let aa = addAnns (ann l) bs cs + return (L (SrcSpanAnn aa (locA l)) a) + +reA :: MonadP m => Located a -> LocatedA b -> [AddApiAnn] -> m (LocatedA b) +reA x y@(L la b) bs = do + let l = comb2A x y + amsA (L (SrcSpanAnn (ann la) l) b) bs amsr :: MonadP m => Located a -> [AddApiAnn] -> m (LocatedA a) amsr a@(L l _) bs = do @@ -4194,6 +4186,9 @@ amsL sp bs = addAnnsAt sp bs >> return () ajs :: MonadP m => (ApiAnnComments -> Located a) -> [AddApiAnn] -> m (Maybe (Located a)) ajs a bs = Just <$> ams a bs +acsj :: MonadP m => (ApiAnnComments -> Located a) -> m (Maybe (Located a)) +acsj a = Just <$> acs a + -- |Add a list of AddApiAnns to the given AST element, where the AST element is the -- result of a monadic action amms :: MonadP m => m (Located a) -> [AddApiAnn] -> m (Located a) @@ -4224,6 +4219,12 @@ amsu a bs = do cs <- addAnnsAt l bs return (unitOL (a cs)) +amcsu :: (ApiAnnComments -> Located a) -> P (OrdList (Located a)) +amcsu a = do + let (L l _) = a [] + cs <- addAnnsAt l [] + return (unitOL (a cs)) + -- |Synonyms for AddApiAnn versions of AnnOpen and AnnClose mo,mc :: Located Token -> AddApiAnn mo ll = mj AnnOpen ll @@ -4294,4 +4295,9 @@ allocateCommentsS :: SrcSpan -> P [RealLocated AnnotationComment] allocateCommentsS (RealSrcSpan l _) = allocateCommentsP l allocateCommentsS _ = return [] +addAnnotationA :: MonadP m => LocatedA a -> AnnKeywordId -> SrcSpan -> m (LocatedA a) +addAnnotationA (L la a) kw span = do + cs <- addAnnsAt (locA la) [] + let anns' = addAnns (ann la) [AddApiAnn kw span] cs + return (L (SrcSpanAnn anns' (locA la)) a) } ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -169,7 +169,7 @@ mkClassDecl :: SrcSpan -> Located (Maybe (LHsContext GhcPs), LHsType GhcPs) -> Located (a,[LHsFunDep GhcPs]) -> OrdList (LHsDecl GhcPs) - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls annsIn @@ -179,7 +179,7 @@ mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls annsIn ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan ; (tyvars,annst) <- checkTyVars (text "class") whereDots cls tparams ; cs2 <- addAnnsAt loc annst -- Add any API Annotations to the top SrcSpan - ; let anns' = addAnns annsIn (ann++annst) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann++annst) (cs1 ++ cs2) ; return (L loc (ClassDecl { tcdCExt = anns', tcdCtxt = cxt , tcdLName = cls, tcdTyVars = tyvars , tcdFixity = fixity @@ -196,7 +196,7 @@ mkTyData :: SrcSpan -> Maybe (LHsKind GhcPs) -> [LConDecl GhcPs] -> HsDeriving GhcPs - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkTyData loc new_or_data cType (L _ (mcxt, tycl_hdr)) ksig data_cons maybe_deriv annsIn @@ -204,7 +204,7 @@ mkTyData loc new_or_data cType (L _ (mcxt, tycl_hdr)) ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] ; (tyvars, anns) <- checkTyVars (ppr new_or_data) equalsDots tc tparams ; cs2 <- addAnnsAt loc anns -- Add any API Annotations to the top SrcSpan [temp] - ; let anns' = addAnns annsIn (ann ++ anns) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann ++ anns) (cs1 ++ cs2) ; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv ; return (L loc (DataDecl { tcdDExt = anns', tcdLName = tc, tcdTyVars = tyvars, @@ -232,14 +232,14 @@ mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv mkTySynonym :: SrcSpan -> LHsType GhcPs -- LHS -> LHsType GhcPs -- RHS - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkTySynonym loc lhs rhs annsIn = do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] ; (tyvars, anns) <- checkTyVars (text "type") equalsDots tc tparams ; cs2 <- addAnnsAt loc anns -- Add any API Annotations to the top SrcSpan [temp] - ; let anns' = addAnns annsIn (ann ++ anns) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann ++ anns) (cs1 ++ cs2) ; return (L loc (SynDecl { tcdSExt = anns' , tcdLName = tc, tcdTyVars = tyvars , tcdFixity = fixity @@ -249,12 +249,13 @@ mkStandaloneKindSig :: SrcSpan -> Located [LocatedA RdrName] -- LHS -> LHsKind GhcPs -- RHS - -> ApiAnn + -> [AddApiAnn] -> P (LStandaloneKindSig GhcPs) mkStandaloneKindSig loc lhs rhs anns = do { vs <- mapM check_lhs_name (unLoc lhs) ; v <- check_singular_lhs (reverse vs) - ; return $ L loc $ StandaloneKindSig anns v (mkLHsSigType rhs) } + ; cs <- addAnnsAt loc [] + ; return $ L loc $ StandaloneKindSig (ApiAnn anns cs) v (mkLHsSigType rhs) } where check_lhs_name :: LocatedA RdrName -> P (LocatedA RdrName) -- AZ temp check_lhs_name v@(unLoc->name) = @@ -272,20 +273,22 @@ mkStandaloneKindSig loc lhs rhs anns = 2 (pprWithCommas ppr vs) , text "See https://gitlab.haskell.org/ghc/ghc/issues/16754 for details." ] -mkTyFamInstEqn :: Maybe [LHsTyVarBndr GhcPs] +mkTyFamInstEqn :: SrcSpan + -> Maybe [LHsTyVarBndr GhcPs] -> LHsType GhcPs -> LHsType GhcPs - -> P (TyFamInstEqn GhcPs,[AddApiAnn]) -mkTyFamInstEqn bndrs lhs rhs + -> [AddApiAnn] + -> P (LTyFamInstEqn GhcPs) +mkTyFamInstEqn loc bndrs lhs rhs anns = do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs - ; return (mkHsImplicitBndrs - (FamEqn { feqn_ext = noExtField + ; cs <- addAnnsAt loc [] + ; return (L (noAnnSrcSpan loc) $ mkHsImplicitBndrs + (FamEqn { feqn_ext = ApiAnn anns cs , feqn_tycon = tc , feqn_bndrs = bndrs , feqn_pats = tparams , feqn_fixity = fixity - , feqn_rhs = rhs }), - ann) } + , feqn_rhs = rhs })) } mkDataFamInst :: SrcSpan -> NewOrData @@ -295,16 +298,17 @@ mkDataFamInst :: SrcSpan -> Maybe (LHsKind GhcPs) -> [LConDecl GhcPs] -> HsDeriving GhcPs - -> ApiAnn + -> [AddApiAnn] -> P (LInstDecl GhcPs) mkDataFamInst loc new_or_data cType (mcxt, bndrs, tycl_hdr) ksig data_cons maybe_deriv anns = do { (tc, tparams, fixity, ann) <- checkTyClHdr False tycl_hdr ; -- AZ:TODO: deal with these comments - ; _cs <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] + ; cs <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] + ; let anns' = addAnns (ApiAnn ann cs) anns [] ; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv - ; return (L loc (DataFamInstD anns (DataFamInstDecl (mkHsImplicitBndrs - (FamEqn { feqn_ext = noExtField + ; return (L loc (DataFamInstD anns' (DataFamInstDecl (mkHsImplicitBndrs + (FamEqn { feqn_ext = noAnn -- AZ: get anns , feqn_tycon = tc , feqn_bndrs = bndrs , feqn_pats = tparams @@ -313,24 +317,25 @@ mkDataFamInst loc new_or_data cType (mcxt, bndrs, tycl_hdr) mkTyFamInst :: SrcSpan -> TyFamInstEqn GhcPs - -> ApiAnn + -> [AddApiAnn] -> P (LInstDecl GhcPs) -mkTyFamInst loc eqn anns - = return (L loc (TyFamInstD anns (TyFamInstDecl eqn))) +mkTyFamInst loc eqn anns = do + cs <- addAnnsAt loc [] + return (L loc (TyFamInstD (ApiAnn anns cs) (TyFamInstDecl eqn))) mkFamDecl :: SrcSpan -> FamilyInfo GhcPs -> LHsType GhcPs -- LHS -> Located (FamilyResultSig GhcPs) -- Optional result signature -> Maybe (LInjectivityAnn GhcPs) -- Injectivity annotation - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkFamDecl loc info lhs ksig injAnn annsIn = do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] ; (tyvars, anns) <- checkTyVars (ppr info) equals_or_where tc tparams ; cs2 <- addAnnsAt loc anns -- Add any API Annotations to the top SrcSpan [temp] - ; let anns' = addAnns annsIn (ann++anns) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann++anns) (cs1 ++ cs2) ; return (L loc (FamDecl anns' (FamilyDecl { fdExt = noExtField , fdInfo = info, fdLName = tc @@ -2699,7 +2704,7 @@ mkInlinePragma src (inl, match_info) mb_act mkImport :: Located CCallConv -> Located Safety -> (Located StringLiteral, LocatedA RdrName, LHsSigType GhcPs) - -> P (HsDecl GhcPs) + -> P (ApiAnn -> HsDecl GhcPs) mkImport cconv safety (L loc (StringLiteral esrc entity), v, ty) = case unLoc cconv of CCallConv -> mkCImport @@ -2728,8 +2733,8 @@ mkImport cconv safety (L loc (StringLiteral esrc entity), v, ty) = funcTarget = CFunction (StaticTarget esrc entity' Nothing True) importSpec = CImport cconv safety Nothing funcTarget (L loc esrc) - returnSpec spec = return $ ForD noExtField $ ForeignImport - { fd_i_ext = noExtField + returnSpec spec = return $ \ann -> ForD noExtField $ ForeignImport + { fd_i_ext = ann , fd_name = v , fd_sig_ty = ty , fd_fi = spec @@ -2800,10 +2805,10 @@ parseCImport cconv safety nm str sourceText = -- mkExport :: Located CCallConv -> (Located StringLiteral, LocatedA RdrName, LHsSigType GhcPs) - -> P (HsDecl GhcPs) + -> P (ApiAnn -> HsDecl GhcPs) mkExport (L lc cconv) (L le (StringLiteral esrc entity), v, ty) - = return $ ForD noExtField $ - ForeignExport { fd_e_ext = noExtField, fd_name = v, fd_sig_ty = ty + = return $ \ann -> ForD noExtField $ + ForeignExport { fd_e_ext = ann, fd_name = v, fd_sig_ty = ty , fd_fe = CExport (L lc (CExportStatic esrc entity' cconv)) (L le esrc) } where @@ -2888,11 +2893,11 @@ mkTypeImpExp name = text "Illegal keyword 'type' (use ExplicitNamespaces to enable)" return (fmap (`setRdrNameSpace` tcClsName) name) -checkImportSpec :: Located [LIE GhcPs] -> P (Located [LIE GhcPs]) +checkImportSpec :: LocatedA [LIE GhcPs] -> P (LocatedA [LIE GhcPs]) checkImportSpec ie@(L _ specs) = case [l | (L l (IEThingWith _ _ (IEWildcard _) _ _)) <- specs] of [] -> return ie - (l:_) -> importSpecError l + (l:_) -> importSpecError (locA l) where importSpecError l = addFatalError l @@ -2982,7 +2987,7 @@ data PV_Context = data PV_Accum = PV_Accum { pv_messages :: DynFlags -> Messages - , pv_annotations :: [(ApiAnnKey,[RealSrcSpan])] + -- AZ , pv_annotations :: [(ApiAnnKey,[RealSrcSpan])] , pv_comment_q :: [RealLocated AnnotationComment] , pv_annotations_comments :: [(RealSrcSpan,[RealLocated AnnotationComment])] } @@ -3017,12 +3022,12 @@ runPV_msg msg m = , pv_hint = msg } pv_acc = PV_Accum { pv_messages = messages s - , pv_annotations = annotations s + -- , pv_annotations = annotations s , pv_comment_q = comment_q s , pv_annotations_comments = annotations_comments s } mkPState acc' = s { messages = pv_messages acc' - , annotations = pv_annotations acc' + -- AZ , annotations = pv_annotations acc' , comment_q = pv_comment_q acc' , annotations_comments = pv_annotations_comments acc' } in @@ -3054,10 +3059,12 @@ instance MonadP PV where let (comment_q', new_ann_comments) = allocateComments l (pv_comment_q acc) annotations_comments' = new_ann_comments ++ pv_annotations_comments acc - annotations' = ((l,a), [v]) : pv_annotations acc + -- annotations' = ((l,a), [v]) : pv_annotations acc acc' = acc - { pv_annotations = annotations' - , pv_comment_q = comment_q' + { + -- AZ pv_annotations = annotations' + -- , + pv_comment_q = comment_q' , pv_annotations_comments = annotations_comments' } in PV_Ok acc' () ===================================== compiler/typecheck/TcBackpack.hs ===================================== @@ -166,7 +166,7 @@ checkHsigIface tcg_env gr sig_iface -- TODO: maybe we can be a little more -- precise here and use the Located -- info for the *specific* name we matched. - -> getLoc e + -> getLocA e _ -> nameSrcSpan name addErrAt loc (badReexportedBootThing False name name') @@ -575,7 +575,7 @@ mergeSignatures -- a signature package (i.e., does not expose any -- modules.) If so, we can thin it. | isFromSignaturePackage - -> setSrcSpan loc $ do + -> setSrcSpan (locA loc) $ do -- Suppress missing errors; they might be used to refer -- to entities from other signatures we are merging in. -- If an identifier truly doesn't exist in any of the @@ -629,7 +629,7 @@ mergeSignatures is_mod = mod_name, is_as = mod_name, is_qual = False, - is_dloc = loc + is_dloc = locA loc } ImpAll rdr_env = mkGlobalRdrEnv (gresFromAvails (Just ispec) as1) setGblEnv tcg_env { ===================================== compiler/typecheck/TcHsSyn.hs ===================================== @@ -1493,7 +1493,7 @@ zonkForeignExport _ for_imp = return for_imp -- Foreign imports don't need zonking zonkRules :: ZonkEnv -> [LRuleDecl GhcTcId] -> TcM [LRuleDecl GhcTc] -zonkRules env rs = mapM (wrapLocM (zonkRule env)) rs +zonkRules env rs = mapM (wrapLocMA (zonkRule env)) rs zonkRule :: ZonkEnv -> RuleDecl GhcTcId -> TcM (RuleDecl GhcTc) zonkRule env rule@(HsRule { rd_tmvs = tm_bndrs{-::[RuleBndr TcId]-} ===================================== compiler/typecheck/TcInstDcls.hs ===================================== @@ -572,7 +572,7 @@ tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn })) -- (1) do the work of verifying the synonym group ; co_ax_branch <- tcTyFamInstEqn fam_tc mb_clsinfo - (L (locA $ getLoc fam_lname) eqn) + (L (getLoc fam_lname) eqn) -- (2) check for validity ===================================== compiler/typecheck/TcRnDriver.hs ===================================== @@ -207,7 +207,7 @@ tcRnModuleTcRnM :: HscEnv tcRnModuleTcRnM hsc_env mod_sum (HsParsedModule { hpm_module = - (L loc (HsModule maybe_mod export_ies + (L loc (HsModule _anns maybe_mod export_ies import_decls local_decls mod_deprec maybe_doc_hdr)), hpm_src_files = src_files @@ -244,9 +244,9 @@ tcRnModuleTcRnM hsc_env mod_sum $ implicitRequirements hsc_env (map simplifyImport (prel_imports ++ import_decls)) - ; let { mkImport (Nothing, L _ mod_name) = noLoc + ; let { mkImport (Nothing, L _ mod_name) = noLocA $ (simpleImportDecl mod_name) - { ideclHiding = Just (False, noLoc [])} + { ideclHiding = Just (False, noLocA [])} ; mkImport _ = panic "mkImport" } ; let { all_imports = prel_imports ++ import_decls ++ map mkImport (raw_sig_imports ++ raw_req_imports) } @@ -396,7 +396,7 @@ tcRnImports hsc_env import_decls tcRnSrcDecls :: Bool -- False => no 'module M(..) where' header at all -> [LHsDecl GhcPs] -- Declarations - -> Maybe (Located [LIE GhcPs]) + -> Maybe (LocatedA [LIE GhcPs]) -> TcM TcGblEnv tcRnSrcDecls explicit_mod_hdr decls export_ies = do { -- Do all the declarations @@ -1716,7 +1716,7 @@ tcTyClsInstDecls tycl_decls deriv_decls binds -} checkMain :: Bool -- False => no 'module M(..) where' header at all - -> Maybe (Located [LIE GhcPs]) -- Export specs of Main module + -> Maybe (LocatedA [LIE GhcPs]) -- Export specs of Main module -> TcM TcGblEnv -- If we are in module Main, check that 'main' is defined and exported. checkMain explicit_mod_hdr export_ies @@ -1724,7 +1724,7 @@ checkMain explicit_mod_hdr export_ies ; tcg_env <- getGblEnv ; check_main dflags tcg_env explicit_mod_hdr export_ies } -check_main :: DynFlags -> TcGblEnv -> Bool -> Maybe (Located [LIE GhcPs]) +check_main :: DynFlags -> TcGblEnv -> Bool -> Maybe (LocatedA [LIE GhcPs]) -> TcM TcGblEnv check_main dflags tcg_env explicit_mod_hdr export_ies | mod /= main_mod @@ -1834,7 +1834,7 @@ check_main dflags tcg_env explicit_mod_hdr export_ies -- Select the main functions from the export list. -- Only the module name is needed, the function name is fixed. - selExportMains :: Maybe (Located [LIE GhcPs]) -> [ModuleName] -- #16453 + selExportMains :: Maybe (LocatedA [LIE GhcPs]) -> [ModuleName] -- #16453 selExportMains Nothing = [main_mod_nm] -- no main specified, but there is a header. selExportMains (Just exps) = fmap fst $ ===================================== compiler/typecheck/TcRnExports.hs ===================================== @@ -152,7 +152,7 @@ type ExportOccMap = OccEnv (Name, IE GhcPs) -- that have the same occurrence name tcRnExports :: Bool -- False => no 'module M(..) where' header at all - -> Maybe (Located [LIE GhcPs]) -- Nothing => no explicit export list + -> Maybe (LocatedA [LIE GhcPs]) -- Nothing => no explicit export list -> TcGblEnv -> RnM TcGblEnv @@ -184,7 +184,7 @@ tcRnExports explicit_mod exports ; let real_exports | explicit_mod = exports | has_main - = Just (noLoc [noLoc (IEVar noAnn + = Just (noLocA [noLocA (IEVar noAnn (noLoc (IEName $ noLocA default_main)))]) -- ToDo: the 'noLoc' here is unhelpful if 'main' -- turns out to be out of scope @@ -212,7 +212,7 @@ tcRnExports explicit_mod exports ; failIfErrsM ; return new_tcg_env } -exports_from_avail :: Maybe (Located [LIE GhcPs]) +exports_from_avail :: Maybe (LocatedA [LIE GhcPs]) -- ^ 'Nothing' means no explicit export list -> GlobalRdrEnv -> ImportAvails @@ -262,7 +262,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod where do_litem :: ExportAccum -> LIE GhcPs -> RnM (Maybe (ExportAccum, (LIE GhcRn, Avails))) - do_litem acc lie = setSrcSpan (getLoc lie) (exports_from_item acc lie) + do_litem acc lie = setSrcSpan (getLocA lie) (exports_from_item acc lie) -- Maps a parent to its in-scope children kids_env :: NameEnv [GlobalRdrElt] ===================================== compiler/typecheck/TcRnMonad.hs ===================================== @@ -60,7 +60,7 @@ module TcRnMonad( -- * Error management getSrcSpanM, setSrcSpan, addLocM, addLocMA, - wrapLocM, wrapLocFstM, wrapLocSndM,wrapLocM_,wrapLocMA, + wrapLocM, wrapLocFstM, wrapLocFstMA, wrapLocSndM,wrapLocM_,wrapLocMA, getErrsVar, setErrsVar, addErr, failWith, failAt, @@ -851,6 +851,12 @@ wrapLocFstM fn (L loc a) = (b,c) <- fn a return (L loc b, c) +wrapLocFstMA :: (a -> TcM (b,c)) -> LocatedA a -> TcM (LocatedA b, c) +wrapLocFstMA fn (L loc a) = + setSrcSpan (locA loc) $ do + (b,c) <- fn a + return (L loc b, c) + wrapLocSndM :: (a -> TcM (b, c)) -> Located a -> TcM (b, Located c) wrapLocSndM fn (L loc a) = setSrcSpan loc $ do ===================================== compiler/typecheck/TcRnTypes.hs ===================================== @@ -509,7 +509,7 @@ data TcGblEnv -- The binds, rules and foreign-decl fields are collected -- initially in un-zonked form and are finally zonked in tcRnSrcDecls - tcg_rn_exports :: Maybe [(Located (IE GhcRn), Avails)], + tcg_rn_exports :: Maybe [(LIE GhcRn, Avails)], -- Nothing <=> no explicit export list -- Is always Nothing if we don't want to retain renamed -- exports. ===================================== compiler/typecheck/TcRules.hs ===================================== @@ -105,7 +105,7 @@ tcRules decls = mapM (wrapLocM tcRuleDecls) decls tcRuleDecls :: RuleDecls GhcRn -> TcM (RuleDecls GhcTcId) tcRuleDecls (HsRules { rds_src = src , rds_rules = decls }) - = do { tc_decls <- mapM (wrapLocM tcRule) decls + = do { tc_decls <- mapM (wrapLocMA tcRule) decls ; return $ HsRules { rds_ext = noExtField , rds_src = src , rds_rules = tc_decls } } ===================================== compiler/typecheck/TcTyClsDecls.hs ===================================== @@ -2620,7 +2620,7 @@ tcInjectivity _ Nothing -- therefore we can always infer the result kind if we know the result type. -- But this does not seem to be useful in any way so we don't do it. (Another -- reason is that the implementation would not be straightforward.) -tcInjectivity tcbs (Just (L loc (InjectivityAnn _ lInjNames))) +tcInjectivity tcbs (Just (L loc (InjectivityAnn _ _ lInjNames))) = setSrcSpan loc $ do { let tvs = binderVars tcbs ; dflags <- getDynFlags @@ -2751,7 +2751,7 @@ kcTyFamInstEqn tc_fam_tc , feqn_bndrs = mb_expl_bndrs , feqn_pats = hs_pats , feqn_rhs = hs_rhs_ty }})) - = setSrcSpan loc $ + = setSrcSpan (locA loc) $ do { traceTc "kcTyFamInstEqn" (vcat [ text "tc_name =" <+> ppr eqn_tc_name , text "fam_tc =" <+> ppr tc_fam_tc <+> dcolon <+> ppr (tyConKind tc_fam_tc) @@ -2793,7 +2793,7 @@ tcTyFamInstEqn fam_tc mb_clsinfo , feqn_pats = hs_pats , feqn_rhs = hs_rhs_ty }})) = ASSERT( getName fam_tc == eqn_tc_name ) - setSrcSpan loc $ + setSrcSpan (locA loc) $ do { traceTc "tcTyFamInstEqn" $ vcat [ ppr fam_tc <+> ppr hs_pats , text "fam tc bndrs" <+> pprTyVars (tyConTyVars fam_tc) @@ -2815,7 +2815,7 @@ tcTyFamInstEqn fam_tc mb_clsinfo -- (tcFamInstEqnGuts zonks to Type) ; return (mkCoAxBranch qtvs [] [] fam_tc pats rhs_ty (map (const Nominal) qtvs) - loc) } + (locA loc)) } tcTyFamInstEqn _ _ _ = panic "tcTyFamInstEqn" ===================================== compiler/utils/OrdList.hs ===================================== @@ -16,6 +16,7 @@ module OrdList ( OrdList, nilOL, isNilOL, unitOL, appOL, consOL, snocOL, concatOL, lastOL, headOL, + initOL, tailOL, unsnocOL, unconsOL, mapOL, fromOL, toOL, foldrOL, foldlOL, reverseOL, fromOLReverse, strictlyEqOL, strictlyOrdOL ) where @@ -73,6 +74,10 @@ concatOL :: [OrdList a] -> OrdList a headOL :: OrdList a -> a lastOL :: OrdList a -> a lengthOL :: OrdList a -> Int +initOL :: OrdList a -> OrdList a +tailOL :: OrdList a -> OrdList a +unsnocOL :: OrdList a -> (OrdList a, a) +unconsOL :: OrdList a -> (a, OrdList a) nilOL = None unitOL as = One as @@ -94,6 +99,36 @@ lastOL (Cons _ as) = lastOL as lastOL (Snoc _ a) = a lastOL (Two _ as) = lastOL as +initOL None = panic "initOL" +initOL (One _) = None +initOL (Many [_]) = None +initOL (Many as) = Many (init as) +initOL (Cons a (Many [_])) = One a +initOL (Cons a (One _)) = One a +initOL (Cons a as) = Cons a (initOL as) +initOL (Snoc as _) = as +initOL (Two as (Many [_])) = as +initOL (Two as (One _)) = as +initOL (Two as bs) = Two as (initOL bs) + +tailOL None = panic "initOL" +tailOL (One _) = None +tailOL (Many [_]) = None +tailOL (Many as) = Many (tail as) +tailOL (Cons _ as) = as +tailOL (Snoc (Many [_]) b) = One b +tailOL (Snoc (One _) b) = One b +tailOL (Snoc as b) = Snoc (tailOL as) b +tailOL (Two (Many [_]) bs) = bs +tailOL (Two (One _) bs) = bs +tailOL (Two as bs) = Two (tailOL as) bs + +unconsOL None = panic "unconsOL" +unconsOL as = (headOL as, tailOL as) + +unsnocOL None = panic "unsnocOL" +unsnocOL as = (initOL as, lastOL as) + lengthOL None = 0 lengthOL (One _) = 1 lengthOL (Many as) = length as View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/069d05b4de11e34da562fe63ac451f990743d504 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/069d05b4de11e34da562fe63ac451f990743d504 You're receiving 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 2 00:36:44 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 20:36:44 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sjakobi/graph-newtype Message-ID: <5e85339ccbb33_616776d1c74236396a@gitlab.haskell.org.mail> Simon Jakobi pushed new branch wip/sjakobi/graph-newtype at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/graph-newtype You're receiving 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 2 00:59:09 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 20:59:09 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] 2 commits: Use the argument order of the deterministic folds Message-ID: <5e8538ddb216f_61673f81cca05dd82367297@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 286c1dd9 by Simon Jakobi at 2020-04-02T02:50:13+02:00 Use the argument order of the deterministic folds - - - - - 960b9951 by Simon Jakobi at 2020-04-02T02:58:53+02:00 Use strict folds in GraphOps - - - - - 18 changed files: - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/typecheck/TcEvidence.hs - compiler/typecheck/TcSimplify.hs - compiler/typecheck/TcType.hs - compiler/utils/GraphOps.hs Changes: ===================================== compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs ===================================== @@ -554,7 +554,7 @@ delAssoc :: (Uniquable a) delAssoc a m | Just aSet <- lookupUFM m a , m1 <- delFromUFM m a - = nonDetStrictFoldUniqSet (\m x -> delAssoc1 x a m) m1 aSet + = nonDetStrictFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet -- It's OK to use nonDetStrictFoldUFM here because deletion is commutative | otherwise = m ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -378,7 +378,7 @@ famInstEnvElts fi = [elt | FamIE elts <- eltsUDFM fi, elt <- elts] -- See Note [FamInstEnv determinism] famInstEnvSize :: FamInstEnv -> Int -famInstEnvSize = nonDetStrictFoldUDFM (\sum (FamIE elt) -> sum + length elt) 0 +famInstEnvSize = nonDetStrictFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 -- It's OK to use nonDetStrictFoldUDFM here since we're just computing the -- size. ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -2502,7 +2502,7 @@ addOneOcc ud id info plus_zapped old new = doZapping ud id old `addOccInfo` new addManyOccsSet :: UsageDetails -> VarSet -> UsageDetails -addManyOccsSet usage id_set = nonDetStrictFoldUniqSet (flip addManyOccs) usage id_set +addManyOccsSet usage id_set = nonDetStrictFoldUniqSet addManyOccs usage id_set -- It's OK to use nonDetStrictFoldUFM here because addManyOccs commutes -- Add several occurrences, assumed not to be tail calls ===================================== compiler/GHC/Core/Op/SetLevels.hs ===================================== @@ -1472,8 +1472,8 @@ countFreeIds :: DVarSet -> Int countFreeIds = nonDetStrictFoldUDFM add 0 . getUniqDSet -- It's OK to use nonDetStrictFoldUDFM here because we're just counting things. where - add :: Int -> Var -> Int - add n v | isId v = n+1 + add :: Var -> Int -> Int + add v n | isId v = n+1 | otherwise = n {- @@ -1581,12 +1581,12 @@ placeJoinCeiling le@(LE { le_ctxt_lvl = lvl }) maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level maxFvLevel max_me env var_set - = nonDetStrictFoldDVarSet (flip (maxIn max_me env)) tOP_LEVEL var_set + = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet maxFvLevel' max_me env var_set - = nonDetStrictFoldUniqSet (flip (maxIn max_me env)) tOP_LEVEL var_set + = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -2177,7 +2177,7 @@ unionCallInfoSet (CIS f calls1) (CIS _ calls2) = callDetailsFVs :: CallDetails -> VarSet callDetailsFVs calls = - nonDetStrictFoldUDFM (flip (unionVarSet . callInfoFVs)) emptyVarSet calls + nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering -- immediately by converting to a nondeterministic set. ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -658,7 +658,7 @@ niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet -- remembering that the substitution isn't necessarily idempotent -- This is used in the occurs check, before extending the substitution niSubstTvSet tsubst tvs - = nonDetStrictFoldUniqSet (flip (unionVarSet . get)) emptyVarSet tvs + = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs -- It's OK to nonDetStrictFoldUFM here because we immediately forget the -- ordering by creating a set. where ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -1426,7 +1426,7 @@ toParents rdr_env ns -- It's OK to use nonDetStrictFoldUFM because we immediately forget the -- ordering by creating a set where - add s n = extendNameSet s (getParent rdr_env n) + add n s = extendNameSet s (getParent rdr_env n) getParent :: GlobalRdrEnv -> Name -> Name getParent rdr_env n ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -545,7 +545,7 @@ closureGrowth expander sizer group abs_ids = go -- we lift @f@ newbies = abs_ids `minusDVarSet` clo_fvs' -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ - cost = nonDetStrictFoldDVarSet (\size id -> sizer id + size) 0 newbies - n_occs + cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs go (RhsSk body_dmd body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -280,10 +280,10 @@ foldUDFM k z m = foldr k z (eltsUDFM m) nonDetFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a nonDetFoldUDFM k z (UDFM m _i) = foldr k z $ map taggedFst $ M.elems m -nonDetStrictFoldUDFM :: (a -> elt -> a) -> a -> UniqDFM elt -> a +nonDetStrictFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a nonDetStrictFoldUDFM k z (UDFM m _i) = foldl' k' z m where - k' acc (TaggedVal v _) = k acc v + k' acc (TaggedVal v _) = k v acc eltsUDFM :: UniqDFM elt -> [elt] eltsUDFM (UDFM m _i) = ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -101,7 +101,7 @@ uniqDSetIntersectUniqSet xs ys foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b foldUniqDSet c n (UniqDSet s) = foldUDFM c n s -nonDetStrictFoldUniqDSet :: (b -> a -> b) -> b -> UniqDSet a -> b +nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s elementOfUniqDSet :: Uniquable a => a -> UniqDSet a -> Bool ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -321,8 +321,8 @@ nonDetKeysUFM (UFM m) = map getUnique $ M.keys m nonDetFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a nonDetFoldUFM k z (UFM m) = M.foldr k z m -nonDetStrictFoldUFM :: (a -> elt -> a) -> a -> UniqFM elt -> a -nonDetStrictFoldUFM k z (UFM m) = M.foldl' k z m +nonDetStrictFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -167,7 +167,7 @@ nonDetKeysUniqSet = nonDetKeysUFM . getUniqSet' nonDetFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a nonDetFoldUniqSet c n (UniqSet s) = nonDetFoldUFM c n s -nonDetStrictFoldUniqSet :: (a -> elt -> a) -> a -> UniqSet elt -> a +nonDetStrictFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a nonDetStrictFoldUniqSet c n (UniqSet s) = nonDetStrictFoldUFM c n s -- See Note [Deterministic UniqFM] to learn about nondeterminism. ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -583,7 +583,7 @@ lookupDVarEnv = lookupUDFM foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b foldDVarEnv = foldUDFM -nonDetStrictFoldDVarEnv :: (b -> a -> b) -> b -> DVarEnv a -> b +nonDetStrictFoldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b nonDetStrictFoldDVarEnv = nonDetStrictFoldUDFM mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -295,7 +295,7 @@ dVarSetMinusVarSet = uniqDSetMinusUniqSet foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a foldDVarSet = foldUniqDSet -nonDetStrictFoldDVarSet :: (a -> Var -> a) -> a -> DVarSet -> a +nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet anyDVarSet :: (Var -> Bool) -> DVarSet -> Bool ===================================== compiler/typecheck/TcEvidence.hs ===================================== @@ -501,7 +501,7 @@ evBindMapBinds = foldEvBindMap consBag emptyBag foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) -nonDetStrictFoldEvBindMap :: (a -> EvBind -> a) -> a -> EvBindMap -> a +nonDetStrictFoldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a nonDetStrictFoldEvBindMap k z bs = nonDetStrictFoldDVarEnv k z (ev_bind_varenv bs) filterEvBindMap :: (EvBind -> Bool) -> EvBindMap -> EvBindMap @@ -866,8 +866,8 @@ findNeededEvVars ev_binds seeds -- It's OK to use nonDetStrictFoldUFM here because we immediately -- forget about the ordering by creating a set - add :: VarSet -> Var -> VarSet - add needs v + add :: Var -> VarSet -> VarSet + add v needs | Just ev_bind <- lookupEvBind ev_binds v , EvBind { eb_is_given = is_given, eb_rhs = rhs } <- ev_bind , is_given ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -1862,7 +1862,7 @@ neededEvVars implic@(Implic { ic_given = givens ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var ; let seeds1 = foldr add_implic_seeds old_needs implics - seeds2 = nonDetStrictFoldEvBindMap (flip add_wanted) seeds1 ev_binds + seeds2 = nonDetStrictFoldEvBindMap add_wanted seeds1 ev_binds seeds3 = seeds2 `unionVarSet` tcvs need_inner = findNeededEvVars ev_binds seeds3 live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds ===================================== compiler/typecheck/TcType.hs ===================================== @@ -707,7 +707,7 @@ tcTypeLevel ty -- It's safe to use a non-deterministic fold because `maxTcLevel` is -- commutative. where - add lvl v + add v lvl | isTcTyVar v = lvl `maxTcLevel` tcTyVarLevel v | otherwise = lvl ===================================== compiler/utils/GraphOps.hs ===================================== @@ -63,8 +63,8 @@ addNode k node graph = let -- add back conflict edges from other nodes to this one map_conflict = - nonDetFoldUniqSet -- TODO? - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use nonDetStrictFoldUFM here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeConflicts = addOneToUniqSet (nodeConflicts n) k})) @@ -73,8 +73,8 @@ addNode k node graph -- add back coalesce edges from other nodes to this one map_coalesce = - nonDetFoldUniqSet -- TODO? - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use nonDetStrictFoldUFM here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeCoalesce = addOneToUniqSet (nodeCoalesce n) k})) @@ -476,8 +476,8 @@ freezeNode k else node -- panic "GraphOps.freezeNode: edge to freeze wasn't in the coalesce set" -- If the edge isn't actually in the coelesce set then just ignore it. - fm2 = nonDetFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 -- TODO? - -- It's OK to use nonDetFoldUFM here because the operation + fm2 = nonDetStrictFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 + -- It's OK to use nonDetStrictFoldUFM here because the operation -- is commutative $ nodeCoalesce node View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d058ecc3bb567581d6d2a01d9cd8878b22fd9464...960b9951fc20ceafe61798c2a2f5b1f2caa809fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d058ecc3bb567581d6d2a01d9cd8878b22fd9464...960b9951fc20ceafe61798c2a2f5b1f2caa809fe You're receiving 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 2 01:03:46 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 21:03:46 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] Try a strict fold for closeOverKinds Message-ID: <5e8539f258241_6167c5fa3c82367651@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: e3daee46 by Simon Jakobi at 2020-04-02T03:03:26+02:00 Try a strict fold for closeOverKinds - - - - - 2 changed files: - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Types/Var/Set.hs Changes: ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -441,7 +441,7 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView closeOverKinds :: TyCoVarSet -> TyCoVarSet -- For each element of the input set, -- add the deep free variables of its kind -closeOverKinds vs = nonDetFoldVarSet do_one vs vs -- TODO? +closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs where do_one v acc = appEndo (deep_ty (varType v)) acc ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Types.Var.Set ( sizeVarSet, seqVarSet, elemVarSetByKey, partitionVarSet, pluralVarSet, pprVarSet, - nonDetFoldVarSet, + nonDetFoldVarSet, nonDetStrictFoldVarSet, -- * Deterministic Var set types DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, @@ -157,6 +157,9 @@ mapVarSet = mapUniqSet nonDetFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a nonDetFoldVarSet = nonDetFoldUniqSet +nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a +nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet + fixVarSet :: (VarSet -> VarSet) -- Map the current set to a new set -> VarSet -> VarSet -- (fixVarSet f s) repeatedly applies f to the set s, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e3daee4652c146ca92eefea9493815bac1ce8895 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e3daee4652c146ca92eefea9493815bac1ce8895 You're receiving 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 2 01:08:39 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Wed, 01 Apr 2020 21:08:39 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] Try strict fold in mk_mod_usage_info.ent_map Message-ID: <5e853b173db5c_61673f81cca05dd823680b8@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 9ebc5d39 by Simon Jakobi at 2020-04-02T03:08:03+02:00 Try strict fold in mk_mod_usage_info.ent_map - - - - - 1 changed file: - compiler/GHC/HsToCore/Usage.hs Changes: ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -260,9 +260,9 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names -- ent_map groups together all the things imported and used -- from a particular module ent_map :: ModuleEnv [OccName] - ent_map = nonDetFoldUniqSet add_mv emptyModuleEnv used_names -- TODO? - -- nonDetFoldUFM is OK here. If you follow the logic, we sort by OccName - -- in ent_hashs + ent_map = nonDetStrictFoldUniqSet add_mv emptyModuleEnv used_names + -- nonDetStrictFoldUniqSet is OK here. If you follow the logic, we sort by + -- OccName in ent_hashs where add_mv name mv_map | isWiredInName name = mv_map -- ignore wired-in names View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ebc5d3925902fd43a8e06f72a225ab15d39aa4a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ebc5d3925902fd43a8e06f72a225ab15d39aa4a You're receiving 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 2 05:32:41 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 01:32:41 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17978 Message-ID: <5e8578f952e73_61675cefcac237217a@gitlab.haskell.org.mail> Simon Jakobi pushed new branch wip/T17978 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17978 You're receiving 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 2 05:46:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:46:15 -0400 Subject: [Git][ghc/ghc][master] Re-engineer the binder-swap transformation Message-ID: <5e857c272bd5e_6167120434ec23784ce@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 19 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/simplCore/should_compile/T17901.stdout - testsuite/tests/simplCore/should_compile/T7360.hs - testsuite/tests/simplCore/should_compile/T7360.stderr Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -69,7 +69,7 @@ module GHC.Core ( maybeUnfoldingTemplate, otherCons, isValueUnfolding, isEvaldUnfolding, isCheapUnfolding, isExpandableUnfolding, isConLikeUnfolding, isCompulsoryUnfolding, - isStableUnfolding, isFragileUnfolding, hasSomeUnfolding, + isStableUnfolding, hasCoreUnfolding, hasSomeUnfolding, isBootUnfolding, canUnfold, neverUnfoldGuidance, isStableSource, @@ -1739,14 +1739,13 @@ neverUnfoldGuidance :: UnfoldingGuidance -> Bool neverUnfoldGuidance UnfNever = True neverUnfoldGuidance _ = False -isFragileUnfolding :: Unfolding -> Bool --- An unfolding is fragile if it mentions free variables or --- is otherwise subject to change. A robust one can be kept. --- See Note [Fragile unfoldings] -isFragileUnfolding (CoreUnfolding {}) = True -isFragileUnfolding (DFunUnfolding {}) = True -isFragileUnfolding _ = False - -- NoUnfolding, BootUnfolding, OtherCon are all non-fragile +hasCoreUnfolding :: Unfolding -> Bool +-- An unfolding "has Core" if it contains a Core expression, which +-- may mention free variables. See Note [Fragile unfoldings] +hasCoreUnfolding (CoreUnfolding {}) = True +hasCoreUnfolding (DFunUnfolding {}) = True +hasCoreUnfolding _ = False + -- NoUnfolding, BootUnfolding, OtherCon have no Core canUnfold :: Unfolding -> Bool canUnfold (CoreUnfolding { uf_guidance = g }) = not (neverUnfoldGuidance g) ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -35,7 +35,7 @@ module GHC.Core.FVs ( idFVs, idRuleVars, idRuleRhsVars, stableUnfoldingVars, ruleRhsFreeVars, ruleFreeVars, rulesFreeVars, - rulesFreeVarsDSet, + rulesFreeVarsDSet, mkRuleInfo, ruleLhsFreeIds, ruleLhsFreeIdsList, expr_fvs, @@ -469,6 +469,11 @@ rulesFVs = mapUnionFV ruleFVs rulesFreeVarsDSet :: [CoreRule] -> DVarSet rulesFreeVarsDSet rules = fvDVarSet $ rulesFVs rules +-- | Make a 'RuleInfo' containing a number of 'CoreRule's, suitable +-- for putting into an 'IdInfo' +mkRuleInfo :: [CoreRule] -> RuleInfo +mkRuleInfo rules = RuleInfo rules (rulesFreeVarsDSet rules) + idRuleRhsVars :: (Activation -> Bool) -> Id -> VarSet -- Just the variables free on the *rhs* of a rule idRuleRhsVars is_active id ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -14,10 +14,7 @@ core expression with (hopefully) improved usage information. {-# LANGUAGE CPP, BangPatterns, MultiWayIf, ViewPatterns #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} - -module GHC.Core.Op.OccurAnal ( - occurAnalysePgm, occurAnalyseExpr, occurAnalyseExpr_NoBinderSwap - ) where +module GHC.Core.Op.OccurAnal ( occurAnalysePgm, occurAnalyseExpr ) where #include "HsVersions.h" @@ -30,7 +27,6 @@ import GHC.Core.Utils ( exprIsTrivial, isDefaultAlt, isExpandableApp, import GHC.Core.Arity ( joinRhsArity ) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Types.Name( localiseName ) import GHC.Types.Basic import GHC.Types.Module( Module ) import GHC.Core.Coercion @@ -47,14 +43,14 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set import Util +import Maybes( orElse, isJust ) import Outputable import Data.List -import Control.Arrow ( second ) {- ************************************************************************ * * - occurAnalysePgm, occurAnalyseExpr, occurAnalyseExpr_NoBinderSwap + occurAnalysePgm, occurAnalyseExpr * * ************************************************************************ @@ -92,8 +88,7 @@ occurAnalysePgm this_mod active_unf active_rule imp_rules binds -- a binding that was actually needed (albeit before its -- definition site). #17724 threw this up. - initial_uds = addManyOccsSet emptyDetails - (rulesFreeVars imp_rules) + initial_uds = addManyOccs emptyDetails (rulesFreeVars imp_rules) -- The RULES declarations keep things alive! -- Note [Preventing loops due to imported functions rules] @@ -117,17 +112,9 @@ occurAnalysePgm this_mod active_unf active_rule imp_rules binds bs_usage occurAnalyseExpr :: CoreExpr -> CoreExpr - -- Do occurrence analysis, and discard occurrence info returned -occurAnalyseExpr = occurAnalyseExpr' True -- do binder swap - -occurAnalyseExpr_NoBinderSwap :: CoreExpr -> CoreExpr -occurAnalyseExpr_NoBinderSwap = occurAnalyseExpr' False -- do not do binder swap - -occurAnalyseExpr' :: Bool -> CoreExpr -> CoreExpr -occurAnalyseExpr' enable_binder_swap expr - = snd (occAnal env expr) - where - env = initOccEnv { occ_binder_swap = enable_binder_swap } +-- Do occurrence analysis, and discard occurrence info returned +occurAnalyseExpr expr + = snd (occAnal initOccEnv expr) {- Note [Plugin rules] ~~~~~~~~~~~~~~~~~~~~~~ @@ -672,38 +659,66 @@ tail call with `n` arguments (counting both value and type arguments). Otherwise 'occ_tail' will be 'NoTailCallInfo'. The tail call info flows bottom-up with the rest of 'OccInfo' until it goes on the binder. -Note [Rules and join points] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Join points and unfoldings/rules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + let j2 y = blah + let j x = j2 (x+x) + {-# INLINE [2] j #-} + in case e of { A -> j 1; B -> ...; C -> j 2 } -Things get fiddly with rules. Suppose we have: +Before j is inlined, we'll have occurrences of j2 in +both j's RHS and in its stable unfolding. We want to discover +j2 as a join point. So we must do the adjustRhsUsage thing +on j's RHS. That's why we pass mb_join_arity to calcUnfolding. + +Aame with rules. Suppose we have: let j :: Int -> Int j y = 2 * y - k :: Int -> Int -> Int - {-# RULES "SPEC k 0" k 0 = j #-} + let k :: Int -> Int -> Int + {-# RULES "SPEC k 0" k 0 y = j y #-} k x y = x + 2 * y - in ... - -Now suppose that both j and k appear only as saturated tail calls in the body. -Thus we would like to make them both join points. The rule complicates matters, -though, as its RHS has an unapplied occurrence of j. *However*, if we were to -eta-expand the rule, all would be well: - - {-# RULES "SPEC k 0" forall a. k 0 a = j a #-} - -So conceivably we could notice that a potential join point would have an -"undersaturated" rule and account for it. This would mean we could make -something that's been specialised a join point, for instance. But local bindings -are rarely specialised, and being overly cautious about rules only -costs us anything when, for some `j`: + in case e of { A -> k 1 2; B -> k 3 5; C -> blah } + +We identify k as a join point, and we want j to be a join point too. +Without the RULE it would be, and we don't want the RULE to mess it +up. So provided the join-point arity of k matches the args of the +rule we can allow the tail-cal info from the RHS of the rule to +propagate. + +* Wrinkle for Rec case. In the recursive case we don't know the + join-point arity in advance, when calling occAnalUnfolding and + occAnalRules. (See makeNode.) We don't want to pass Nothing, + because then a recursive joinrec might lose its join-poin-hood + when SpecConstr adds a RULE. So we just make do with the + *current* join-poin-hood, stored in the Id. + + In the non-recursive case things are simple: see occAnalNonRecBind + +* Wrinkle for RULES. Suppose the example was a bit different: + let j :: Int -> Int + j y = 2 * y + k :: Int -> Int -> Int + {-# RULES "SPEC k 0" k 0 = j #-} + k x y = x + 2 * y + in ... + If we eta-expanded the rule all woudl be well, but as it stands the + one arg of the rule don't match the join-point arity of 2. + + Conceivably we could notice that a potential join point would have + an "undersaturated" rule and account for it. This would mean we + could make something that's been specialised a join point, for + instance. But local bindings are rarely specialised, and being + overly cautious about rules only costs us anything when, for some `j`: * Before specialisation, `j` has non-tail calls, so it can't be a join point. * During specialisation, `j` gets specialised and thus acquires rules. * Sometime afterward, the non-tail calls to `j` disappear (as dead code, say), and so now `j` *could* become a join point. -This appears to be very rare in practice. TODO Perhaps we should gather -statistics to be sure. + This appears to be very rare in practice. TODO Perhaps we should gather + statistics to be sure. ------------------------------------------------------------ Note [Adjusting right-hand sides] @@ -767,44 +782,62 @@ occAnalBind env lvl top_env (Rec pairs) body_usage ----------------- occAnalNonRecBind :: OccEnv -> TopLevelFlag -> ImpRuleEdges -> Var -> CoreExpr -> UsageDetails -> (UsageDetails, [CoreBind]) -occAnalNonRecBind env lvl imp_rule_edges binder rhs body_usage - | isTyVar binder -- A type let; we don't gather usage info - = (body_usage, [NonRec binder rhs]) +occAnalNonRecBind env lvl imp_rule_edges bndr rhs body_usage + | isTyVar bndr -- A type let; we don't gather usage info + = (body_usage, [NonRec bndr rhs]) - | not (binder `usedIn` body_usage) -- It's not mentioned + | not (bndr `usedIn` body_usage) -- It's not mentioned = (body_usage, []) | otherwise -- It's mentioned in the body - = (body_usage' `andUDs` rhs_usage', [NonRec tagged_binder rhs']) + = (body_usage' `andUDs` rhs_usage4, [NonRec final_bndr rhs']) where - (body_usage', tagged_binder) = tagNonRecBinder lvl body_usage binder - mb_join_arity = willBeJoinId_maybe tagged_binder + (body_usage', tagged_bndr) = tagNonRecBinder lvl body_usage bndr + occ = idOccInfo tagged_bndr - (bndrs, body) = collectBinders rhs + -- Get the join info from the *new* decision + -- See Note [Join points and unfoldings/rules] + mb_join_arity = willBeJoinId_maybe tagged_bndr + is_join_point = isJust mb_join_arity - (rhs_usage1, bndrs', body') = occAnalNonRecRhs env tagged_binder bndrs body - rhs' = mkLams (markJoinOneShots mb_join_arity bndrs') body' - -- For a /non-recursive/ join point we can mark all - -- its join-lambda as one-shot; and it's a good idea to do so + final_bndr = tagged_bndr `setIdUnfolding` unf' + `setIdSpecialisation` mkRuleInfo rules' + + env1 | is_join_point = env -- See Note [Join point RHSs] + | certainly_inline = env -- See Note [Cascading inlines] + | otherwise = rhsCtxt env + + -- See Note [Sources of one-shot information] + rhs_env = env1 { occ_one_shots = argOneShots dmd } + + (rhs_usage1, rhs') = occAnalRhs rhs_env mb_join_arity rhs -- Unfoldings -- See Note [Unfoldings and join points] - rhs_usage2 = case occAnalUnfolding env NonRecursive binder of - Just unf_usage -> rhs_usage1 `andUDs` unf_usage - Nothing -> rhs_usage1 + unf = idUnfolding bndr + (unf_usage, unf') = occAnalUnfolding rhs_env mb_join_arity unf + rhs_usage2 = rhs_usage1 `andUDs` unf_usage -- Rules -- See Note [Rules are extra RHSs] and Note [Rule dependency info] - rules_w_uds = occAnalRules env mb_join_arity NonRecursive tagged_binder + rules_w_uds = occAnalRules rhs_env mb_join_arity bndr rule_uds = map (\(_, l, r) -> l `andUDs` r) rules_w_uds + rules' = map fstOf3 rules_w_uds rhs_usage3 = foldr andUDs rhs_usage2 rule_uds - rhs_usage4 = case lookupVarEnv imp_rule_edges binder of + rhs_usage4 = case lookupVarEnv imp_rule_edges bndr of Nothing -> rhs_usage3 - Just vs -> addManyOccsSet rhs_usage3 vs + Just vs -> addManyOccs rhs_usage3 vs -- See Note [Preventing loops due to imported functions rules] - -- Final adjustment - rhs_usage' = adjustRhsUsage mb_join_arity NonRecursive bndrs' rhs_usage4 + certainly_inline -- See Note [Cascading inlines] + = case occ of + OneOcc { occ_in_lam = NotInsideLam, occ_one_br = InOneBranch } + -> active && not_stable + _ -> False + + dmd = idDemandInfo bndr + active = isAlwaysActive (idInlineActivation bndr) + not_stable = not (isStableUnfolding (idUnfolding bndr)) ----------------- occAnalRecBind :: OccEnv -> TopLevelFlag -> ImpRuleEdges -> [(Var,CoreExpr)] @@ -866,8 +899,8 @@ occAnalRec env lvl (CyclicSCC details_s) (body_uds, binds) | otherwise -- At this point we always build a single Rec = -- pprTrace "occAnalRec" (vcat - -- [ text "weak_fvs" <+> ppr weak_fvs - -- , text "lb nodes" <+> ppr loop_breaker_nodes]) + -- [ text "weak_fvs" <+> ppr weak_fvs + -- , text "lb nodes" <+> ppr loop_breaker_nodes]) (final_uds, Rec pairs : binds) where @@ -931,10 +964,10 @@ recording inlinings for any Ids which aren't marked as "no-inline" as it goes. -- Return the bindings sorted into a plausible order, and marked with loop breakers. loopBreakNodes depth bndr_set weak_fvs nodes binds = -- pprTrace "loopBreakNodes" (ppr nodes) $ - go (stronglyConnCompFromEdgedVerticesUniqR nodes) binds + go (stronglyConnCompFromEdgedVerticesUniqR nodes) where - go [] binds = binds - go (scc:sccs) binds = loop_break_scc scc (go sccs binds) + go [] = binds + go (scc:sccs) = loop_break_scc scc (go sccs) loop_break_scc scc binds = case scc of @@ -949,7 +982,7 @@ reOrderNodes _ _ _ [] _ = panic "reOrderNodes" reOrderNodes _ _ _ [node] binds = mk_loop_breaker node : binds reOrderNodes depth bndr_set weak_fvs (node : nodes) binds = -- pprTrace "reOrderNodes" (vcat [ text "unchosen" <+> ppr unchosen - -- , text "chosen" <+> ppr chosen_nodes ]) $ + -- , text "chosen" <+> ppr chosen_nodes ]) $ loopBreakNodes new_depth bndr_set weak_fvs unchosen $ (map mk_loop_breaker chosen_nodes ++ binds) where @@ -1148,7 +1181,9 @@ type LetrecNode = Node Unique Details -- Node comes from Digraph -- The Unique key is gotten from the Id data Details = ND { nd_bndr :: Id -- Binder + , nd_rhs :: CoreExpr -- RHS, already occ-analysed + , nd_rhs_bndrs :: [CoreBndr] -- Outer lambdas of RHS -- INVARIANT: (nd_rhs_bndrs nd, _) == -- collectBinders (nd_rhs nd) @@ -1205,7 +1240,7 @@ makeNode env imp_rule_edges bndr_set (bndr, rhs) -- is still deterministic with edges in nondeterministic order as -- explained in Note [Deterministic SCC] in Digraph. where - details = ND { nd_bndr = bndr + details = ND { nd_bndr = bndr' , nd_rhs = rhs' , nd_rhs_bndrs = bndrs' , nd_uds = rhs_usage3 @@ -1214,24 +1249,35 @@ makeNode env imp_rule_edges bndr_set (bndr, rhs) , nd_active_rule_fvs = active_rule_fvs , nd_score = pprPanic "makeNodeDetails" (ppr bndr) } + bndr' = bndr `setIdUnfolding` unf' + `setIdSpecialisation` mkRuleInfo rules' + + -- Get join point info from the *current* decision + -- We don't know what the new decision will be! + -- Using the old decision at least allows us to + -- preserve existing join point, even RULEs are added + -- See Note [Join points and unfoldings/rules] + mb_join_arity = isJoinId_maybe bndr + -- Constructing the edges for the main Rec computation -- See Note [Forming Rec groups] (bndrs, body) = collectBinders rhs - (rhs_usage1, bndrs', body') = occAnalRecRhs env bndrs body - rhs' = mkLams bndrs' body' - rhs_usage2 = foldr andUDs rhs_usage1 rule_uds + rhs_env = rhsCtxt env + (rhs_usage1, bndrs', body') = occAnalLamOrRhs rhs_env bndrs body + rhs' = mkLams bndrs' body' + rhs_usage3 = foldr andUDs rhs_usage1 rule_uds + `andUDs` unf_uds -- Note [Rules are extra RHSs] -- Note [Rule dependency info] - rhs_usage3 = case mb_unf_uds of - Just unf_uds -> rhs_usage2 `andUDs` unf_uds - Nothing -> rhs_usage2 - node_fvs = udFreeVars bndr_set rhs_usage3 + node_fvs = udFreeVars bndr_set rhs_usage3 -- Finding the free variables of the rules is_active = occ_rule_act env :: Activation -> Bool rules_w_uds :: [(CoreRule, UsageDetails, UsageDetails)] - rules_w_uds = occAnalRules env (Just (length bndrs)) Recursive bndr + rules_w_uds = occAnalRules rhs_env mb_join_arity bndr + + rules' = map fstOf3 rules_w_uds rules_w_rhs_fvs :: [(Activation, VarSet)] -- Find the RHS fvs rules_w_rhs_fvs = maybe id (\ids -> ((AlwaysActive, ids):)) @@ -1244,16 +1290,20 @@ makeNode env imp_rule_edges bndr_set (bndr, rhs) , is_active a] -- Finding the usage details of the INLINE pragma (if any) - mb_unf_uds = occAnalUnfolding env Recursive bndr + unf = realIdUnfolding bndr -- realIdUnfolding: Ignore loop-breaker-ness + -- here because that is what we are setting! + (unf_uds, unf') = occAnalUnfolding rhs_env mb_join_arity unf -- Find the "nd_inl" free vars; for the loop-breaker phase - inl_fvs = case mb_unf_uds of - Nothing -> udFreeVars bndr_set rhs_usage1 -- No INLINE, use RHS - Just unf_uds -> udFreeVars bndr_set unf_uds - -- We could check for an *active* INLINE (returning - -- emptyVarSet for an inactive one), but is_active - -- isn't the right thing (it tells about - -- RULE activation), so we'd need more plumbing + -- These are the vars that would become free if the function + -- was inlinined; usually that means the RHS, unless the + -- unfolding is a stable one. + -- Note: We could do this only for functions with an *active* unfolding + -- (returning emptyVarSet for an inactive one), but is_active + -- isn't the right thing (it tells about RULE activation), + -- so we'd need more plumbing + inl_fvs | isStableUnfolding unf = udFreeVars bndr_set unf_uds + | otherwise = udFreeVars bndr_set rhs_usage1 mkLoopBreakerNodes :: OccEnv -> TopLevelFlag -> VarSet @@ -1271,22 +1321,24 @@ mkLoopBreakerNodes :: OccEnv -> TopLevelFlag mkLoopBreakerNodes env lvl bndr_set body_uds details_s = (final_uds, zipWith mk_lb_node details_s bndrs') where - (final_uds, bndrs') = tagRecBinders lvl body_uds - [ ((nd_bndr nd) - ,(nd_uds nd) - ,(nd_rhs_bndrs nd)) - | nd <- details_s ] - mk_lb_node nd@(ND { nd_bndr = bndr, nd_rhs = rhs, nd_inl = inl_fvs }) bndr' - = DigraphNode nd' (varUnique bndr) (nonDetKeysUniqSet lb_deps) + (final_uds, bndrs') + = tagRecBinders lvl body_uds + [ (bndr, uds, rhs_bndrs) + | ND { nd_bndr = bndr, nd_uds = uds, nd_rhs_bndrs = rhs_bndrs } + <- details_s ] + + mk_lb_node nd@(ND { nd_bndr = old_bndr, nd_inl = inl_fvs }) new_bndr + = DigraphNode nd' (varUnique old_bndr) (nonDetKeysUniqSet lb_deps) -- It's OK to use nonDetKeysUniqSet here as -- stronglyConnCompFromEdgedVerticesR is still deterministic with edges -- in nondeterministic order as explained in -- Note [Deterministic SCC] in Digraph. where - nd' = nd { nd_bndr = bndr', nd_score = score } - score = nodeScore env bndr bndr' rhs lb_deps + nd' = nd { nd_bndr = new_bndr, nd_score = score } + score = nodeScore env new_bndr lb_deps nd lb_deps = extendFvs_ rule_fv_env inl_fvs + rule_fv_env :: IdEnv IdSet -- Maps a variable f to the variables from this group -- mentioned in RHS of active rules for f @@ -1301,12 +1353,13 @@ mkLoopBreakerNodes env lvl bndr_set body_uds details_s ------------------------------------------ nodeScore :: OccEnv - -> Id -- Binder has old occ-info (just for loop-breaker-ness) -> Id -- Binder with new occ-info - -> CoreExpr -- RHS -> VarSet -- Loop-breaker dependencies + -> Details -> NodeScore -nodeScore env old_bndr new_bndr bind_rhs lb_deps +nodeScore env new_bndr lb_deps + (ND { nd_bndr = old_bndr, nd_rhs = bind_rhs }) + | not (isId old_bndr) -- A type or coercion variable is never a loop breaker = (100, 0, False) @@ -1324,7 +1377,7 @@ nodeScore env old_bndr new_bndr bind_rhs lb_deps -- where df is the exported dictionary. Then df makes a really -- bad choice for loop breaker - | DFunUnfolding { df_args = args } <- id_unfolding + | DFunUnfolding { df_args = args } <- old_unf -- Never choose a DFun as a loop breaker -- Note [DFuns should not be loop breakers] = (9, length args, is_lb) @@ -1332,13 +1385,13 @@ nodeScore env old_bndr new_bndr bind_rhs lb_deps -- Data structures are more important than INLINE pragmas -- so that dictionary/method recursion unravels - | CoreUnfolding { uf_guidance = UnfWhen {} } <- id_unfolding + | CoreUnfolding { uf_guidance = UnfWhen {} } <- old_unf = mk_score 6 | is_con_app rhs -- Data types help with cases: = mk_score 5 -- Note [Constructor applications] - | isStableUnfolding id_unfolding + | isStableUnfolding old_unf , can_unfold = mk_score 3 @@ -1355,23 +1408,23 @@ nodeScore env old_bndr new_bndr bind_rhs lb_deps mk_score :: Int -> NodeScore mk_score rank = (rank, rhs_size, is_lb) - is_lb = isStrongLoopBreaker (idOccInfo old_bndr) - rhs = case id_unfolding of - CoreUnfolding { uf_src = src, uf_tmpl = unf_rhs } - | isStableSource src - -> unf_rhs - _ -> bind_rhs + -- is_lb: see Note [Loop breakers, node scoring, and stability] + is_lb = isStrongLoopBreaker (idOccInfo old_bndr) + + old_unf = realIdUnfolding old_bndr + can_unfold = canUnfold old_unf + rhs = case old_unf of + CoreUnfolding { uf_src = src, uf_tmpl = unf_rhs } + | isStableSource src + -> unf_rhs + _ -> bind_rhs -- 'bind_rhs' is irrelevant for inlining things with a stable unfolding - rhs_size = case id_unfolding of + rhs_size = case old_unf of CoreUnfolding { uf_guidance = guidance } | UnfIfGoodArgs { ug_size = size } <- guidance -> size _ -> cheapExprSize rhs - can_unfold = canUnfold id_unfolding - id_unfolding = realIdUnfolding old_bndr - -- realIdUnfolding: Ignore loop-breaker-ness here because - -- that is what we are setting! -- Checking for a constructor application -- Cheap and cheerful; the simplifier moves casts out of the way @@ -1508,108 +1561,84 @@ Hence the is_lb field of NodeScore ************************************************************************ -} -occAnalRhs :: OccEnv -> RecFlag -> Id -> [CoreBndr] -> CoreExpr - -> (UsageDetails, [CoreBndr], CoreExpr) - -- Returned usage details covers only the RHS, - -- and *not* the RULE or INLINE template for the Id -occAnalRhs env Recursive _ bndrs body - = occAnalRecRhs env bndrs body -occAnalRhs env NonRecursive id bndrs body - = occAnalNonRecRhs env id bndrs body - -occAnalRecRhs :: OccEnv -> [CoreBndr] -> CoreExpr -- Rhs lambdas, body - -> (UsageDetails, [CoreBndr], CoreExpr) - -- Returned usage details covers only the RHS, - -- and *not* the RULE or INLINE template for the Id -occAnalRecRhs env bndrs body = occAnalLamOrRhs (rhsCtxt env) bndrs body - -occAnalNonRecRhs :: OccEnv - -> Id -> [CoreBndr] -> CoreExpr -- Binder; rhs lams, body - -- Binder is already tagged with occurrence info - -> (UsageDetails, [CoreBndr], CoreExpr) - -- Returned usage details covers only the RHS, - -- and *not* the RULE or INLINE template for the Id -occAnalNonRecRhs env bndr bndrs body - = occAnalLamOrRhs rhs_env bndrs body +occAnalRhs :: OccEnv -> Maybe JoinArity + -> CoreExpr -- RHS + -> (UsageDetails, CoreExpr) +occAnalRhs env mb_join_arity rhs + = (rhs_usage, rhs') where - env1 | is_join_point = env -- See Note [Join point RHSs] - | certainly_inline = env -- See Note [Cascading inlines] - | otherwise = rhsCtxt env - - -- See Note [Sources of one-shot information] - rhs_env = env1 { occ_one_shots = argOneShots dmd } - - certainly_inline -- See Note [Cascading inlines] - = case occ of - OneOcc { occ_in_lam = NotInsideLam, occ_one_br = InOneBranch } - -> active && not_stable - _ -> False - - is_join_point = isAlwaysTailCalled occ - -- Like (isJoinId bndr) but happens one step earlier - -- c.f. willBeJoinId_maybe + (bndrs, body) = collectBinders rhs + (body_usage, bndrs', body') = occAnalLamOrRhs env bndrs body + rhs' = mkLams (markJoinOneShots mb_join_arity bndrs') body' + -- For a /non-recursive/ join point we can mark all + -- its join-lambda as one-shot; and it's a good idea to do so - occ = idOccInfo bndr - dmd = idDemandInfo bndr - active = isAlwaysActive (idInlineActivation bndr) - not_stable = not (isStableUnfolding (idUnfolding bndr)) + -- Final adjustment + rhs_usage = adjustRhsUsage mb_join_arity NonRecursive bndrs' body_usage occAnalUnfolding :: OccEnv - -> RecFlag - -> Id - -> Maybe UsageDetails - -- Just the analysis, not a new unfolding. The unfolding - -- got analysed when it was created and we don't need to - -- update it. -occAnalUnfolding env rec_flag id - = case realIdUnfolding id of -- ignore previous loop-breaker flag - CoreUnfolding { uf_tmpl = rhs, uf_src = src } - | not (isStableSource src) - -> Nothing - | otherwise - -> Just $ markAllMany usage + -> Maybe JoinArity -- See Note [Join points and unfoldings/rules] + -> Unfolding + -> (UsageDetails, Unfolding) +-- Occurrence-analyse a stable unfolding; +-- discard a non-stable one altogether. +occAnalUnfolding env mb_join_arity unf + = case unf of + unf@(CoreUnfolding { uf_tmpl = rhs, uf_src = src }) + | isStableSource src -> (usage, unf') + | otherwise -> (emptyDetails, unf) + where -- For non-Stable unfoldings we leave them undisturbed, but + -- don't count their usage because the simplifier will discard them. + -- We leave them undisturbed because nodeScore uses their size info + -- to guide its decisions. It's ok to leave un-substituted + -- expressions in the tree because all the variables that were in + -- scope remain in scope; there is no cloning etc. + (usage, rhs') = occAnalRhs env mb_join_arity rhs + + unf' | noBinderSwaps env = unf -- Note [Unfoldings and rules] + | otherwise = unf { uf_tmpl = rhs' } + + unf@(DFunUnfolding { df_bndrs = bndrs, df_args = args }) + -> ( final_usage, unf { df_args = args' } ) where - (bndrs, body) = collectBinders rhs - (usage, _, _) = occAnalRhs env rec_flag id bndrs body + env' = env `addInScope` bndrs + (usage, args') = occAnalList env' args + final_usage = zapDetails (delDetailsList usage bndrs) - DFunUnfolding { df_bndrs = bndrs, df_args = args } - -> Just $ zapDetails (delDetailsList usage bndrs) - where - usage = andUDsList (map (fst . occAnal env) args) - - _ -> Nothing + unf -> (emptyDetails, unf) occAnalRules :: OccEnv - -> Maybe JoinArity -- If the binder is (or MAY become) a join - -- point, what its join arity is (or WOULD - -- become). See Note [Rules and join points]. - -> RecFlag - -> Id + -> Maybe JoinArity -- See Note [Join points and unfoldings/rules] + -> Id -- Get rules from here -> [(CoreRule, -- Each (non-built-in) rule UsageDetails, -- Usage details for LHS UsageDetails)] -- Usage details for RHS -occAnalRules env mb_expected_join_arity rec_flag id - = [ (rule, lhs_uds, rhs_uds) | rule at Rule {} <- idCoreRules id - , let (lhs_uds, rhs_uds) = occ_anal_rule rule ] +occAnalRules env mb_join_arity bndr + = map occ_anal_rule (idCoreRules bndr) where - occ_anal_rule (Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs }) - = (lhs_uds, final_rhs_uds) + occ_anal_rule rule@(Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs }) + = (rule', lhs_uds', rhs_uds') where - lhs_uds = addManyOccsSet emptyDetails $ - (exprsFreeVars args `delVarSetList` bndrs) - (rhs_bndrs, rhs_body) = collectBinders rhs - (rhs_uds, _, _) = occAnalRhs env rec_flag id rhs_bndrs rhs_body + env' = env `addInScope` bndrs + rule' | noBinderSwaps env = rule -- Note [Unfoldings and rules] + | otherwise = rule { ru_args = args', ru_rhs = rhs' } + + (lhs_uds, args') = occAnalList env' args + lhs_uds' = markAllMany $ + lhs_uds `delDetailsList` bndrs + + (rhs_uds, rhs') = occAnal env' rhs -- Note [Rules are extra RHSs] -- Note [Rule dependency info] - final_rhs_uds = adjust_tail_info args $ markAllMany $ - (rhs_uds `delDetailsList` bndrs) - occ_anal_rule _ - = (emptyDetails, emptyDetails) - - adjust_tail_info args uds -- see Note [Rules and join points] - = case mb_expected_join_arity of - Just ar | args `lengthIs` ar -> uds - _ -> markAllNonTailCalled uds + rhs_uds' = markAllNonTailCalledIf (not exact_join) $ + markAllMany $ + rhs_uds `delDetailsList` bndrs + + exact_join = exactJoin mb_join_arity args + -- See Note [Join points and unfoldings/rules] + + occ_anal_rule other_rule = (other_rule, emptyDetails, emptyDetails) + {- Note [Join point RHSs] ~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1622,6 +1651,19 @@ the FloatIn pass knows to float into join point RHSs; and the simplifier does not float things out of join point RHSs. But it's a simple, cheap thing to do. See #14137. +Note [Unfoldings and rules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Generally unfoldings and rules are already occurrence-analysed, so we +don't want to reconstruct their trees; we just want to analyse them to +find how they use their free variables. + +EXCEPT if there is a binder-swap going on, in which case we do want to +produce a new tree. + +So we have a fast-path that keeps the old tree if the occ_bs_env is +empty. This just saves a bit of allocation and reconstruction; not +a big deal. + Note [Cascading inlines] ~~~~~~~~~~~~~~~~~~~~~~~~ By default we use an rhsCtxt for the RHS of a binding. This tells the @@ -1674,6 +1716,12 @@ for the various clauses. ************************************************************************ -} +occAnalList :: OccEnv -> [CoreExpr] -> (UsageDetails, [CoreExpr]) +occAnalList _ [] = (emptyDetails, []) +occAnalList env (e:es) = case occAnal env e of { (uds1, e') -> + case occAnalList env es of { (uds2, es') -> + (uds1 `andUDs` uds2, e' : es') } } + occAnal :: OccEnv -> CoreExpr -> (UsageDetails, -- Gives info only about the "interesting" Ids @@ -1690,7 +1738,7 @@ occAnal env expr@(Var _) = occAnalApp env (expr, [], []) -- weren't used at all. occAnal _ (Coercion co) - = (addManyOccsSet emptyDetails (coVarsOfCo co), Coercion co) + = (addManyOccs emptyDetails (coVarsOfCo co), Coercion co) -- See Note [Gather occurrences of coercion variables] {- @@ -1711,7 +1759,7 @@ occAnal env (Tick tickish body) = (markAllNonTailCalled usage, Tick tickish body') | Breakpoint _ ids <- tickish - = (usage_lam `andUDs` foldr addManyOccs emptyDetails ids, Tick tickish body') + = (usage_lam `andUDs` foldr addManyOcc emptyDetails ids, Tick tickish body') -- never substitute for any of the Ids in a Breakpoint | otherwise @@ -1734,7 +1782,7 @@ occAnal env (Cast expr co) -- usage1: if we see let x = y `cast` co -- then mark y as 'Many' so that we don't -- immediately inline y again. - usage2 = addManyOccsSet usage1 (coVarsOfCo co) + usage2 = addManyOccs usage1 (coVarsOfCo co) -- usage2: see Note [Gather occurrences of coercion variables] in (markAllNonTailCalled usage2, Cast expr' co) } @@ -1762,21 +1810,23 @@ occAnal env (Lam x body) -- Then, the simplifier is careful when partially applying lambdas. occAnal env expr@(Lam _ _) - = case occAnalLamOrRhs env binders body of { (usage, tagged_binders, body') -> + = case occAnalLamOrRhs env bndrs body of { (usage, tagged_bndrs, body') -> let - expr' = mkLams tagged_binders body' + expr' = mkLams tagged_bndrs body' usage1 = markAllNonTailCalled usage - one_shot_gp = all isOneShotBndr tagged_binders - final_usage | one_shot_gp = usage1 - | otherwise = markAllInsideLam usage1 + one_shot_gp = all isOneShotBndr tagged_bndrs + final_usage = markAllInsideLamIf (not one_shot_gp) usage1 in (final_usage, expr') } where - (binders, body) = collectBinders expr + (bndrs, body) = collectBinders expr occAnal env (Case scrut bndr ty alts) - = case occ_anal_scrut scrut alts of { (scrut_usage, scrut') -> - case mapAndUnzip occ_anal_alt alts of { (alts_usage_s, alts') -> + = case occAnal (scrutCtxt env alts) scrut of { (scrut_usage, scrut') -> + let alt_env = addBndrSwap scrut' bndr $ + env { occ_encl = OccVanilla } `addInScope` [bndr] + in + case mapAndUnzip (occAnalAlt alt_env) alts of { (alts_usage_s, alts') -> let alts_usage = foldr orUDs emptyDetails alts_usage_s (alts_usage1, tagged_bndr) = tagLamBinder alts_usage bndr @@ -1784,27 +1834,10 @@ occAnal env (Case scrut bndr ty alts) -- Alts can have tail calls, but the scrutinee can't in total_usage `seq` (total_usage, Case scrut' tagged_bndr ty alts') }} - where - alt_env = mkAltEnv env scrut bndr - occ_anal_alt = occAnalAlt alt_env - - occ_anal_scrut (Var v) (alt1 : other_alts) - | not (null other_alts) || not (isDefaultAlt alt1) - = (mkOneOcc env v IsInteresting 0, Var v) - -- The 'True' says that the variable occurs in an interesting - -- context; the case has at least one non-default alternative - occ_anal_scrut (Tick t e) alts - | t `tickishScopesLike` SoftScope - -- No reason to not look through all ticks here, but only - -- for soft-scoped ticks we can do so without having to - -- update returned occurrence info (see occAnal) - = second (Tick t) $ occ_anal_scrut e alts - - occ_anal_scrut scrut _alts - = occAnal (vanillaCtxt env) scrut -- No need for rhsCtxt occAnal env (Let bind body) - = case occAnal env body of { (body_usage, body') -> + = case occAnal (env `addInScope` bindersOf bind) + body of { (body_usage, body') -> case occAnalBind env NotTopLevel noImpRuleEdges bind body_usage of { (final_usage, new_binds) -> @@ -1845,17 +1878,22 @@ Constructors are rather like lambdas in this way. occAnalApp :: OccEnv -> (Expr CoreBndr, [Arg CoreBndr], [Tickish Id]) -> (UsageDetails, Expr CoreBndr) +-- Naked variables (not applied) end up here too occAnalApp env (Var fun, args, ticks) - | null ticks = (uds, mkApps (Var fun) args') - | otherwise = (uds, mkTicks ticks $ mkApps (Var fun) args') + | null ticks = (all_uds, mkApps fun' args') + | otherwise = (all_uds, mkTicks ticks $ mkApps fun' args') where - uds = fun_uds `andUDs` final_args_uds + (fun', fun_id') = lookupVarEnv (occ_bs_env env) fun + `orElse` (Var fun, fun) + -- See Note [The binder-swap substitution] + + fun_uds = mkOneOcc fun_id' int_cxt n_args + all_uds = fun_uds `andUDs` final_args_uds !(args_uds, args') = occAnalArgs env args one_shots - !final_args_uds - | isRhsEnv env && is_exp = markAllNonTailCalled $ - markAllInsideLam args_uds - | otherwise = markAllNonTailCalled args_uds + !final_args_uds = markAllNonTailCalled $ + markAllInsideLamIf (isRhsEnv env && is_exp) $ + args_uds -- We mark the free vars of the argument of a constructor or PAP -- as "inside-lambda", if it is the RHS of a let(rec). -- This means that nothing gets inlined into a constructor or PAP @@ -1868,7 +1906,11 @@ occAnalApp env (Var fun, args, ticks) n_val_args = valArgCount args n_args = length args - fun_uds = mkOneOcc env fun (if n_val_args > 0 then IsInteresting else NotInteresting) n_args + int_cxt = case occ_encl env of + OccScrut -> IsInteresting + _other | n_val_args > 0 -> IsInteresting + | otherwise -> NotInteresting + is_exp = isExpandableApp fun n_val_args -- See Note [CONLIKE pragma] in GHC.Types.Basic -- The definition of is_exp should match that in GHC.Core.Op.Simplify.prepareRhs @@ -1891,11 +1933,6 @@ occAnalApp env (fun, args, ticks) -- onto the context stack. !(args_uds, args') = occAnalArgs env args [] -zapDetailsIf :: Bool -- If this is true - -> UsageDetails -- Then do zapDetails on this - -> UsageDetails -zapDetailsIf True uds = zapDetails uds -zapDetailsIf False uds = uds {- Note [Sources of one-shot information] @@ -1987,9 +2024,12 @@ scrutinised y). occAnalLamOrRhs :: OccEnv -> [CoreBndr] -> CoreExpr -> (UsageDetails, [CoreBndr], CoreExpr) +-- Tags the returned binders with their OccInfo, but does +-- not do any markInsideLam to the returned usage details occAnalLamOrRhs env [] body = case occAnal env body of (body_usage, body') -> (body_usage, [], body') -- RHS of thunk or nullary join point + occAnalLamOrRhs env (bndr:bndrs) body | isTyVar bndr = -- Important: Keep the environment so that we don't inline into an RHS like @@ -1997,6 +2037,7 @@ occAnalLamOrRhs env (bndr:bndrs) body -- (see the beginning of Note [Cascading inlines]). case occAnalLamOrRhs env bndrs body of (body_usage, bndrs', body') -> (body_usage, bndr:bndrs', body') + occAnalLamOrRhs env binders body = case occAnal env_body body of { (body_usage, body') -> let @@ -2005,47 +2046,17 @@ occAnalLamOrRhs env binders body in (final_usage, tagged_binders, body') } where - (env_body, binders') = oneShotGroup env binders + env1 = env `addInScope` binders + (env_body, binders') = oneShotGroup env1 binders -occAnalAlt :: (OccEnv, Maybe (Id, CoreExpr)) - -> CoreAlt - -> (UsageDetails, Alt IdWithOccInfo) -occAnalAlt (env, scrut_bind) (con, bndrs, rhs) - = case occAnal env rhs of { (rhs_usage1, rhs1) -> +occAnalAlt :: OccEnv -> CoreAlt -> (UsageDetails, Alt IdWithOccInfo) +occAnalAlt env (con, bndrs, rhs) + = case occAnal (env `addInScope` bndrs) rhs of { (rhs_usage1, rhs1) -> let (alt_usg, tagged_bndrs) = tagLamBinders rhs_usage1 bndrs - -- See Note [Binders in case alternatives] - (alt_usg', rhs2) = wrapAltRHS env scrut_bind alt_usg tagged_bndrs rhs1 - in - (alt_usg', (con, tagged_bndrs, rhs2)) } - -wrapAltRHS :: OccEnv - -> Maybe (Id, CoreExpr) -- proxy mapping generated by mkAltEnv - -> UsageDetails -- usage for entire alt (p -> rhs) - -> [Var] -- alt binders - -> CoreExpr -- alt RHS - -> (UsageDetails, CoreExpr) -wrapAltRHS env (Just (scrut_var, let_rhs)) alt_usg bndrs alt_rhs - | occ_binder_swap env - , scrut_var `usedIn` alt_usg -- bndrs are not be present in alt_usg so this - -- handles condition (a) in Note [Binder swap] - , not captured -- See condition (b) in Note [Binder swap] - = ( alt_usg' `andUDs` let_rhs_usg - , Let (NonRec tagged_scrut_var let_rhs') alt_rhs ) - where - captured = any (`usedIn` let_rhs_usg) bndrs -- Check condition (b) - - -- The rhs of the let may include coercion variables - -- if the scrutinee was a cast, so we must gather their - -- usage. See Note [Gather occurrences of coercion variables] - -- Moreover, the rhs of the let may mention the case-binder, and - -- we want to gather its occ-info as well - (let_rhs_usg, let_rhs') = occAnal env let_rhs - - (alt_usg', tagged_scrut_var) = tagLamBinder alt_usg scrut_var + in -- See Note [Binders in case alternatives] + (alt_usg, (con, tagged_bndrs, rhs1)) } -wrapAltRHS _ _ alt_usg _ alt_rhs - = (alt_usg, alt_rhs) {- ************************************************************************ @@ -2058,18 +2069,17 @@ wrapAltRHS _ _ alt_usg _ alt_rhs data OccEnv = OccEnv { occ_encl :: !OccEncl -- Enclosing context information , occ_one_shots :: !OneShots -- See Note [OneShots] - , occ_gbl_scrut :: GlobalScruts - - , occ_unf_act :: Id -> Bool -- Which Id unfoldings are active - - , occ_rule_act :: Activation -> Bool -- Which rules are active + , occ_unf_act :: Id -> Bool -- Which Id unfoldings are active + , occ_rule_act :: Activation -> Bool -- Which rules are active -- See Note [Finding rule RHS free vars] - , occ_binder_swap :: !Bool -- enable the binder_swap - -- See CorePrep Note [Dead code in CorePrep] + -- See Note [The binder-swap substitution] + , occ_bs_env :: VarEnv (OutExpr, OutId) + , occ_bs_rng :: VarSet -- Vars free in the range of occ_bs_env + -- Domain is Global and Local Ids + -- Range is just Local Ids } -type GlobalScruts = IdSet -- See Note [Binder swap on GlobalId scrutinees] ----------------------------- -- OccEncl is used to control whether to inline into constructor arguments @@ -2079,15 +2089,22 @@ type GlobalScruts = IdSet -- See Note [Binder swap on GlobalId scrutinees] -- z = f (p,q) -- Do inline p,q; it may make a rule fire -- So OccEncl tells enough about the context to know what to do when -- we encounter a constructor application or PAP. +-- +-- OccScrut is used to set the "interesting context" field of OncOcc data OccEncl - = OccRhs -- RHS of let(rec), albeit perhaps inside a type lambda - -- Don't inline into constructor args here - | OccVanilla -- Argument of function, body of lambda, scruintee of case etc. - -- Do inline into constructor args here + = OccRhs -- RHS of let(rec), albeit perhaps inside a type lambda + -- Don't inline into constructor args here + + | OccScrut -- Scrutintee of a case + -- Can inline into constructor args + + | OccVanilla -- Argument of function, body of lambda, etc + -- Do inline into constructor args here instance Outputable OccEncl where ppr OccRhs = text "occRhs" + ppr OccScrut = text "occScrut" ppr OccVanilla = text "occVanilla" -- See note [OneShots] @@ -2097,15 +2114,30 @@ initOccEnv :: OccEnv initOccEnv = OccEnv { occ_encl = OccVanilla , occ_one_shots = [] - , occ_gbl_scrut = emptyVarSet + -- To be conservative, we say that all -- inlines and rules are active , occ_unf_act = \_ -> True , occ_rule_act = \_ -> True - , occ_binder_swap = True } -vanillaCtxt :: OccEnv -> OccEnv -vanillaCtxt env = env { occ_encl = OccVanilla, occ_one_shots = [] } + , occ_bs_env = emptyVarEnv + , occ_bs_rng = emptyVarSet } + +noBinderSwaps :: OccEnv -> Bool +noBinderSwaps (OccEnv { occ_bs_env = bs_env }) = isEmptyVarEnv bs_env + +scrutCtxt :: OccEnv -> [CoreAlt] -> OccEnv +scrutCtxt env alts + | interesting_alts = env { occ_encl = OccScrut, occ_one_shots = [] } + | otherwise = env { occ_encl = OccVanilla, occ_one_shots = [] } + where + interesting_alts = case alts of + [] -> False + [alt] -> not (isDefaultAlt alt) + _ -> True + -- 'interesting_alts' is True if the case has at least one + -- non-default alternative. That in turn influences + -- pre/postInlineUnconditionally. Grep for "occ_int_cxt"! rhsCtxt :: OccEnv -> OccEnv rhsCtxt env = env { occ_encl = OccRhs, occ_one_shots = [] } @@ -2117,8 +2149,15 @@ argCtxt env (one_shots:one_shots_s) = (env { occ_encl = OccVanilla, occ_one_shots = one_shots }, one_shots_s) isRhsEnv :: OccEnv -> Bool -isRhsEnv (OccEnv { occ_encl = OccRhs }) = True -isRhsEnv (OccEnv { occ_encl = OccVanilla }) = False +isRhsEnv (OccEnv { occ_encl = cxt }) = case cxt of + OccRhs -> True + _ -> False + +addInScope :: OccEnv -> [Var] -> OccEnv +-- See Note [The binder-swap substitution] +addInScope env@(OccEnv { occ_bs_env = swap_env, occ_bs_rng = rng_vars }) bndrs + | any (`elemVarSet` rng_vars) bndrs = env { occ_bs_env = emptyVarEnv, occ_bs_rng = emptyVarSet } + | otherwise = env { occ_bs_env = swap_env `delVarEnvList` bndrs } oneShotGroup :: OccEnv -> [CoreBndr] -> ( OccEnv @@ -2222,14 +2261,14 @@ scrutinee of a case for occurrences of the case-binder: (1) case x of b { pi -> ri } ==> - case x of b { pi -> let x=b in ri } + case x of b { pi -> ri[b/x] } (2) case (x |> co) of b { pi -> ri } ==> - case (x |> co) of b { pi -> let x = b |> sym co in ri } + case (x |> co) of b { pi -> ri[b |> sym co/x] } -In both cases, the trivial 'let' can be eliminated by the -immediately following simplifier pass. +The substitution ri[b/x] etc is done by the occurrence analyser. +See Note [The binder-swap substitution]. There are two reasons for making this swap: @@ -2257,20 +2296,6 @@ There are two reasons for making this swap: The same can happen even if the scrutinee is a variable with a cast: see Note [Case of cast] -In both cases, in a particular alternative (pi -> ri), we only -add the binding if - (a) x occurs free in (pi -> ri) - (ie it occurs in ri, but is not bound in pi) - (b) the pi does not bind b (or the free vars of co) -We need (a) and (b) for the inserted binding to be correct. - -For the alternatives where we inject the binding, we can transfer -all x's OccInfo to b. And that is the point. - -Notice that - * The deliberate shadowing of 'x'. - * That (a) rapidly becomes false, so no bindings are injected. - The reason for doing these transformations /here in the occurrence analyser/ is because it allows us to adjust the OccInfo for 'x' and 'b' as we go. @@ -2279,15 +2304,9 @@ analyser/ is because it allows us to adjust the OccInfo for 'x' and ri; then this transformation makes it occur just once, and hence get inlined right away. - * If instead we do this in the Simplifier, we don't know whether 'x' - is used in ri, so we are forced to pessimistically zap b's OccInfo - even though it is typically dead (ie neither it nor x appear in - the ri). There's nothing actually wrong with zapping it, except - that it's kind of nice to know which variables are dead. My nose - tells me to keep this information as robustly as possible. - -The Maybe (Id,CoreExpr) passed to occAnalAlt is the extra let-binding -{x=b}; it's Nothing if the binder-swap doesn't happen. + * If instead the Simplifier replaces occurrences of x with + occurrences of b, that will mess up b's occurrence info. That in + turn might have consequences. There is a danger though. Consider let v = x +# y @@ -2299,6 +2318,75 @@ same simplifier pass that reduced (f v) to v. I think this is just too bad. CSE will recover some of it. +Note [The binder-swap substitution] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The binder-swap is implemented by the occ_bs_env field of OccEnv. +Given case x |> co of b { alts } +we add [x :-> (b |> sym co)] to the occ_bs_env environment; this is +done by addBndrSwap. Then, at an occurrence of a variable, we look +up in the occ_bs_env to perform the swap. See occAnalApp. + +Some tricky corners: + +* We do the substitution before gathering occurrence info. So in + the above example, an occurrence of x turns into an occurrence + of b, and that's what we gather in the UsageDetails. It's as + if the binder-swap occurred before occurrence analysis. + +* We need care when shadowing. Suppose [x :-> b] is in occ_bs_env, + and we encounter: + - \x. blah + Here we want to delete the x-binding from occ_bs_env + + - \b. blah + This is harder: we really want to delete all bindings that + have 'b' free in the range. That is a bit tiresome to implement, + so we compromise. We keep occ_bs_rng, which is the set of + free vars of rng(occc_bs_env). If a binder shadows any of these + variables, we discard all of occ_bs_env. Safe, if a bit + brutal. NB, however: the simplifer de-shadows the code, so the + next time around this won't happen. + + These checks are implemented in addInScope. + +* The occurrence analyser itself does /not/ do cloning. It could, in + principle, but it'd make it a bit more complicated and there is no + great benefit. The simplifer uses cloning to get a no-shadowing + situation, the care-when-shadowing behaviour above isn't needed for + long. + +* The domain of occ_bs_env can include GlobaIds. Eg + case M.foo of b { alts } + We extend occ_bs_env with [M.foo :-> b]. That's fine. + +* We have to apply the substitution uniformly, including to rules and + unfoldings. + +Historical note +--------------- +We used to do the binder-swap transformation by introducing +a proxy let-binding, thus; + + case x of b { pi -> ri } + ==> + case x of b { pi -> let x = b in ri } + +But that had two problems: + +1. If 'x' is an imported GlobalId, we'd end up with a GlobalId + on the LHS of a let-binding which isn't allowed. We worked + around this for a while by "localising" x, but it turned + out to be very painful #16296, + +2. In CorePrep we use the occurrence analyser to do dead-code + elimination (see Note [Dead code in CorePrep]). But that + occasionally led to an unlifted let-binding + case x of b { DEFAULT -> let x::Int# = b in ... } + which disobeys one of CorePrep's output invariants (no unlifted + let-bindings) -- see #5433. + +Doing a substitution (via occ_bs_env) is much better. + Note [Case of cast] ~~~~~~~~~~~~~~~~~~~ Consider case (x `cast` co) of b { I# -> @@ -2307,25 +2395,12 @@ We'd like to eliminate the inner case. That is the motivation for equation (2) in Note [Binder swap]. When we get to the inner case, we inline x, cancel the casts, and away we go. -Note [Binder swap on GlobalId scrutinees] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When the scrutinee is a GlobalId we must take care in two ways - - i) In order to *know* whether 'x' occurs free in the RHS, we need its - occurrence info. BUT, we don't gather occurrence info for - GlobalIds. That's the reason for the (small) occ_gbl_scrut env in - OccEnv is for: it says "gather occurrence info for these". - - ii) We must call localiseId on 'x' first, in case it's a GlobalId, or - has an External Name. See, for example, SimplEnv Note [Global Ids in - the substitution]. - Note [Zap case binders in proxy bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From the original case x of cb(dead) { p -> ...x... } we will get - case x of cb(live) { p -> let x = cb in ...x... } + case x of cb(live) { p -> ...cb... } Core Lint never expects to find an *occurrence* of an Id marked as Dead, so we must zap the OccInfo on cb before making the @@ -2396,37 +2471,25 @@ binder-swap unconditionally and still get occurrence analysis information right. -} -mkAltEnv :: OccEnv -> CoreExpr -> Id -> (OccEnv, Maybe (Id, CoreExpr)) --- Does three things: a) makes the occ_one_shots = OccVanilla --- b) extends the GlobalScruts if possible --- c) returns a proxy mapping, binding the scrutinee --- to the case binder, if possible -mkAltEnv env@(OccEnv { occ_gbl_scrut = pe }) scrut case_bndr - = case stripTicksTopE (const True) scrut of - Var v -> add_scrut v case_bndr' - Cast (Var v) co -> add_scrut v (Cast case_bndr' (mkSymCo co)) - -- See Note [Case of cast] - _ -> (env { occ_encl = OccVanilla }, Nothing) +addBndrSwap :: OutExpr -> Id -> OccEnv -> OccEnv +-- See Note [The binder-swap substitution] +addBndrSwap scrut case_bndr + env@(OccEnv { occ_bs_env = swap_env, occ_bs_rng = rng_vars }) + | Just (v, rhs) <- try_swap (stripTicksTopE (const True) scrut) + = env { occ_bs_env = extendVarEnv swap_env v (rhs, case_bndr') + , occ_bs_rng = rng_vars `unionVarSet` exprFreeVars rhs } + | otherwise + = env where - add_scrut v rhs - | isGlobalId v = (env { occ_encl = OccVanilla }, Nothing) - | otherwise = ( env { occ_encl = OccVanilla - , occ_gbl_scrut = pe `extendVarSet` v } - , Just (localise v, rhs) ) - -- ToDO: this isGlobalId stuff is a TEMPORARY FIX - -- to avoid the binder-swap for GlobalIds - -- See #16346 - - case_bndr' = Var (zapIdOccInfo case_bndr) - -- See Note [Zap case binders in proxy bindings] - - -- Localise the scrut_var before shadowing it; we're making a - -- new binding for it, and it might have an External Name, or - -- even be a GlobalId; Note [Binder swap on GlobalId scrutinees] - -- Also we don't want any INLINE or NOINLINE pragmas! - localise scrut_var = mkLocalIdOrCoVar (localiseName (idName scrut_var)) - (idType scrut_var) + try_swap :: OutExpr -> Maybe (OutVar, OutExpr) + try_swap (Var v) = Just (v, Var case_bndr') + try_swap (Cast (Var v) co) = Just (v, Cast (Var case_bndr') (mkSymCo co)) + -- See Note [Case of cast] + try_swap _ = Nothing + + case_bndr' = zapIdOccInfo case_bndr + -- See Note [Zap case binders in proxy bindings] {- ************************************************************************ @@ -2437,7 +2500,6 @@ mkAltEnv env@(OccEnv { occ_gbl_scrut = pe }) scrut case_bndr Note [UsageDetails and zapping] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - On many occasions, we must modify all gathered occurrence data at once. For instance, all occurrences underneath a (non-one-shot) lambda set the 'occ_in_lam' flag to become 'True'. We could use 'mapVarEnv' to do this, but @@ -2476,45 +2538,36 @@ andUDs, orUDs andUDs = combineUsageDetailsWith addOccInfo orUDs = combineUsageDetailsWith orOccInfo -andUDsList :: [UsageDetails] -> UsageDetails -andUDsList = foldl' andUDs emptyDetails - -mkOneOcc :: OccEnv -> Id -> InterestingCxt -> JoinArity -> UsageDetails -mkOneOcc env id int_cxt arity +mkOneOcc ::Id -> InterestingCxt -> JoinArity -> UsageDetails +mkOneOcc id int_cxt arity | isLocalId id - = singleton $ OneOcc { occ_in_lam = NotInsideLam - , occ_one_br = InOneBranch - , occ_int_cxt = int_cxt - , occ_tail = AlwaysTailCalled arity } - | id `elemVarSet` occ_gbl_scrut env - = singleton noOccInfo - + = emptyDetails { ud_env = unitVarEnv id occ_info } | otherwise = emptyDetails where - singleton info = emptyDetails { ud_env = unitVarEnv id info } - -addOneOcc :: UsageDetails -> Id -> OccInfo -> UsageDetails -addOneOcc ud id info - = ud { ud_env = extendVarEnv_C plus_zapped (ud_env ud) id info } - `alterZappedSets` (`delVarEnv` id) - where - plus_zapped old new = doZapping ud id old `addOccInfo` new + occ_info = OneOcc { occ_in_lam = NotInsideLam + , occ_one_br = InOneBranch + , occ_int_cxt = int_cxt + , occ_tail = AlwaysTailCalled arity } -addManyOccsSet :: UsageDetails -> VarSet -> UsageDetails -addManyOccsSet usage id_set = nonDetFoldUniqSet addManyOccs usage id_set - -- It's OK to use nonDetFoldUFM here because addManyOccs commutes +addManyOccId :: UsageDetails -> Id -> UsageDetails +-- Add the non-committal (id :-> noOccInfo) to the usage details +addManyOccId ud id = ud { ud_env = extendVarEnv (ud_env ud) id noOccInfo } -- Add several occurrences, assumed not to be tail calls -addManyOccs :: Var -> UsageDetails -> UsageDetails -addManyOccs v u | isId v = addOneOcc u v noOccInfo - | otherwise = u +addManyOcc :: Var -> UsageDetails -> UsageDetails +addManyOcc v u | isId v = addManyOccId u v + | otherwise = u -- Give a non-committal binder info (i.e noOccInfo) because -- a) Many copies of the specialised thing can appear -- b) We don't want to substitute a BIG expression inside a RULE -- even if that's the only occurrence of the thing -- (Same goes for INLINE.) +addManyOccs :: UsageDetails -> VarSet -> UsageDetails +addManyOccs usage id_set = nonDetFoldUniqSet addManyOcc usage id_set + -- It's OK to use nonDetFoldUFM here because addManyOcc commutes + delDetails :: UsageDetails -> Id -> UsageDetails delDetails ud bndr = ud `alterUsageDetails` (`delVarEnv` bndr) @@ -2538,8 +2591,23 @@ markAllMany ud = ud { ud_z_many = ud_env ud } markAllInsideLam ud = ud { ud_z_in_lam = ud_env ud } markAllNonTailCalled ud = ud { ud_z_no_tail = ud_env ud } +markAllInsideLamIf, markAllNonTailCalledIf :: Bool -> UsageDetails -> UsageDetails + +markAllInsideLamIf True ud = markAllInsideLam ud +markAllInsideLamIf False ud = ud + +markAllNonTailCalledIf True ud = markAllNonTailCalled ud +markAllNonTailCalledIf False ud = ud + + zapDetails = markAllMany . markAllNonTailCalled -- effectively sets to noOccInfo +zapDetailsIf :: Bool -- If this is true + -> UsageDetails -- Then do zapDetails on this + -> UsageDetails +zapDetailsIf True uds = zapDetails uds +zapDetailsIf False uds = uds + lookupDetails :: UsageDetails -> Id -> OccInfo lookupDetails ud id | isCoVar id -- We do not currently gather occurrence info (from types) @@ -2595,14 +2663,17 @@ doZapping ud var occ = doZappingByUnique ud (varUnique var) occ doZappingByUnique :: UsageDetails -> Unique -> OccInfo -> OccInfo -doZappingByUnique ud uniq - = (if | in_subset ud_z_many -> markMany - | in_subset ud_z_in_lam -> markInsideLam - | otherwise -> id) . - (if | in_subset ud_z_no_tail -> markNonTailCalled - | otherwise -> id) +doZappingByUnique (UD { ud_z_many = many + , ud_z_in_lam = in_lam + , ud_z_no_tail = no_tail }) + uniq occ + = occ2 where - in_subset field = uniq `elemVarEnvByKey` field ud + occ1 | uniq `elemVarEnvByKey` many = markMany occ + | uniq `elemVarEnvByKey` in_lam = markInsideLam occ + | otherwise = occ + occ2 | uniq `elemVarEnvByKey` no_tail = markNonTailCalled occ1 + | otherwise = occ1 alterZappedSets :: UsageDetails -> (ZappedSet -> ZappedSet) -> UsageDetails alterZappedSets ud f @@ -2612,8 +2683,7 @@ alterZappedSets ud f alterUsageDetails :: UsageDetails -> (OccInfoEnv -> OccInfoEnv) -> UsageDetails alterUsageDetails ud f - = ud { ud_env = f (ud_env ud) } - `alterZappedSets` f + = ud { ud_env = f (ud_env ud) } `alterZappedSets` f flattenUsageDetails :: UsageDetails -> UsageDetails flattenUsageDetails ud @@ -2623,25 +2693,26 @@ flattenUsageDetails ud ------------------- -- See Note [Adjusting right-hand sides] adjustRhsUsage :: Maybe JoinArity -> RecFlag - -> [CoreBndr] -- Outer lambdas, AFTER occ anal - -> UsageDetails -> UsageDetails + -> [CoreBndr] -- Outer lambdas, AFTER occ anal + -> UsageDetails -- From body of lambda + -> UsageDetails adjustRhsUsage mb_join_arity rec_flag bndrs usage - = maybe_mark_lam (maybe_drop_tails usage) + = markAllInsideLamIf (not one_shot) $ + markAllNonTailCalledIf (not exact_join) $ + usage where - maybe_mark_lam ud | one_shot = ud - | otherwise = markAllInsideLam ud - maybe_drop_tails ud | exact_join = ud - | otherwise = markAllNonTailCalled ud - one_shot = case mb_join_arity of Just join_arity | isRec rec_flag -> False | otherwise -> all isOneShotBndr (drop join_arity bndrs) Nothing -> all isOneShotBndr bndrs - exact_join = case mb_join_arity of - Just join_arity -> bndrs `lengthIs` join_arity - _ -> False + exact_join = exactJoin mb_join_arity bndrs + +exactJoin :: Maybe JoinArity -> [a] -> Bool +exactJoin Nothing _ = False +exactJoin (Just join_arity) args = args `lengthIs` join_arity + -- Remember join_arity includes type binders type IdWithOccInfo = Id @@ -2668,7 +2739,7 @@ tagLamBinder usage bndr bndr' = setBinderOcc (markNonTailCalled occ) bndr -- Don't try to make an argument into a join point usage1 = usage `delDetails` bndr - usage2 | isId bndr = addManyOccsSet usage1 (idUnfoldingVars bndr) + usage2 | isId bndr = addManyOccs usage1 (idUnfoldingVars bndr) -- This is effectively the RHS of a -- non-join-point binding, so it's okay to use -- addManyOccsSet, which assumes no tail calls ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -45,7 +45,8 @@ import GHC.Core.Unfold import GHC.Core.Utils import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg , joinPointBinding_maybe, joinPointBindings_maybe ) -import GHC.Core.Rules ( mkRuleInfo, lookupRule, getRules ) +import GHC.Core.FVs ( mkRuleInfo ) +import GHC.Core.Rules ( lookupRule, getRules ) import GHC.Types.Basic ( TopLevelFlag(..), isNotTopLevel, isTopLevel, RecFlag(..), Arity ) import MonadUtils ( mapAccumLM, liftIO ) @@ -1422,7 +1423,7 @@ simplLamBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr) -- fw a b x{=(a,b)} = ... -- The "{=(a,b)}" is an unfolding we can't reconstruct otherwise. simplLamBndr env bndr - | isId bndr && isFragileUnfolding old_unf -- Special case + | isId bndr && hasCoreUnfolding old_unf -- Special case = do { (env1, bndr1) <- simplBinder env bndr ; unf' <- simplStableUnfolding env1 NotTopLevel Nothing bndr old_unf (idType bndr1) @@ -2883,7 +2884,7 @@ the unfolding (a,b), and *that* mentions b. If f has a RULE RULE f (p, I# q) = ... we want that rule to match, so we must extend the in-scope env with a suitable unfolding for 'y'. It's *essential* for rule matching; but -it's also good for case-elimintation -- suppose that 'f' was inlined +it's also good for case-elimination -- suppose that 'f' was inlined and did multi-level case analysis, then we'd solve it in one simplifier sweep instead of two. ===================================== compiler/GHC/Core/Op/Simplify/Utils.hs ===================================== @@ -1872,22 +1872,26 @@ Historical note: if you use let-bindings instead of a substitution, beware of th prepareAlts tries these things: -1. Eliminate alternatives that cannot match, including the - DEFAULT alternative. +1. filterAlts: eliminate alternatives that cannot match, including + the DEFAULT alternative. Here "cannot match" includes knowledge + from GADTs -2. If the DEFAULT alternative can match only one possible constructor, - then make that constructor explicit. +2. refineDefaultAlt: if the DEFAULT alternative can match only one + possible constructor, then make that constructor explicit. e.g. case e of x { DEFAULT -> rhs } ===> case e of x { (a,b) -> rhs } where the type is a single constructor type. This gives better code when rhs also scrutinises x or e. + See CoreUtils Note [Refine DEFAULT case alternatives] -3. Returns a list of the constructors that cannot holds in the - DEFAULT alternative (if there is one) +3. combineIdenticalAlts: combine identical alternatives into a DEFAULT. + See CoreUtils Note [Combine identical alternatives], which also + says why we do this on InAlts not on OutAlts -Here "cannot match" includes knowledge from GADTs +4. Returns a list of the constructors that cannot holds in the + DEFAULT alternative (if there is one) It's a good idea to do this stuff before simplifying the alternatives, to avoid simplifying alternatives we know can't happen, and to come up with ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -17,7 +17,7 @@ module GHC.Core.Rules ( ruleCheckProgram, -- ** Manipulating 'RuleInfo' rules - mkRuleInfo, extendRuleInfo, addRuleInfo, + extendRuleInfo, addRuleInfo, addIdSpecialisations, -- * Misc. CoreRule helpers @@ -279,11 +279,6 @@ pprRulesForUser dflags rules ************************************************************************ -} --- | Make a 'RuleInfo' containing a number of 'CoreRule's, suitable --- for putting into an 'IdInfo' -mkRuleInfo :: [CoreRule] -> RuleInfo -mkRuleInfo rules = RuleInfo rules (rulesFreeVarsDSet rules) - extendRuleInfo :: RuleInfo -> [CoreRule] -> RuleInfo extendRuleInfo (RuleInfo rs1 fvs1) rs2 = RuleInfo (rs2 ++ rs1) (rulesFreeVarsDSet rs2 `unionDVarSet` fvs1) ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -618,7 +618,7 @@ substIdInfo subst new_id info where old_rules = ruleInfo info old_unf = unfoldingInfo info - nothing_to_do = isEmptyRuleInfo old_rules && not (isFragileUnfolding old_unf) + nothing_to_do = isEmptyRuleInfo old_rules && not (hasCoreUnfolding old_unf) ------------------ -- | Substitutes for the 'Id's within an unfolding ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -22,9 +22,9 @@ find, unsurprisingly, a Core expression. module GHC.Core.Unfold ( Unfolding, UnfoldingGuidance, -- Abstract types - noUnfolding, mkImplicitUnfolding, + noUnfolding, mkUnfolding, mkCoreUnfolding, - mkTopUnfolding, mkSimpleUnfolding, mkWorkerUnfolding, + mkFinalUnfolding, mkSimpleUnfolding, mkWorkerUnfolding, mkInlineUnfolding, mkInlineUnfoldingWithArity, mkInlinableUnfolding, mkWwInlineRule, mkCompulsoryUnfolding, mkDFunUnfolding, @@ -48,12 +48,12 @@ import GhcPrelude import GHC.Driver.Session import GHC.Core -import GHC.Core.Op.OccurAnal ( occurAnalyseExpr_NoBinderSwap ) +import GHC.Core.Op.OccurAnal ( occurAnalyseExpr ) import GHC.Core.SimpleOpt import GHC.Core.Arity ( manifestArity ) import GHC.Core.Utils import GHC.Types.Id -import GHC.Types.Demand ( isBottomingSig ) +import GHC.Types.Demand ( StrictSig, isBottomingSig ) import GHC.Core.DataCon import GHC.Types.Literal import PrimOp @@ -80,14 +80,22 @@ import Data.List ************************************************************************ -} -mkTopUnfolding :: DynFlags -> Bool -> CoreExpr -> Unfolding -mkTopUnfolding dflags is_bottoming rhs - = mkUnfolding dflags InlineRhs True is_bottoming rhs +mkFinalUnfolding :: DynFlags -> UnfoldingSource -> StrictSig -> CoreExpr -> Unfolding +-- "Final" in the sense that this is a GlobalId that will not be further +-- simplified; so the unfolding should be occurrence-analysed +mkFinalUnfolding dflags src strict_sig expr + = mkUnfolding dflags src + True {- Top level -} + (isBottomingSig strict_sig) + expr + +mkCompulsoryUnfolding :: CoreExpr -> Unfolding +mkCompulsoryUnfolding expr -- Used for things that absolutely must be unfolded + = mkCoreUnfolding InlineCompulsory True + (simpleOptExpr unsafeGlobalDynFlags expr) + (UnfWhen { ug_arity = 0 -- Arity of unfolding doesn't matter + , ug_unsat_ok = unSaturatedOk, ug_boring_ok = boringCxtOk }) -mkImplicitUnfolding :: DynFlags -> CoreExpr -> Unfolding --- For implicit Ids, do a tiny bit of optimising first -mkImplicitUnfolding dflags expr - = mkTopUnfolding dflags False (simpleOptExpr dflags expr) -- Note [Top-level flag on inline rules] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -103,7 +111,7 @@ mkDFunUnfolding :: [Var] -> DataCon -> [CoreExpr] -> Unfolding mkDFunUnfolding bndrs con ops = DFunUnfolding { df_bndrs = bndrs , df_con = con - , df_args = map occurAnalyseExpr_NoBinderSwap ops } + , df_args = map occurAnalyseExpr ops } -- See Note [Occurrence analysis of unfoldings] mkWwInlineRule :: DynFlags -> CoreExpr -> Arity -> Unfolding @@ -113,13 +121,6 @@ mkWwInlineRule dflags expr arity (UnfWhen { ug_arity = arity, ug_unsat_ok = unSaturatedOk , ug_boring_ok = boringCxtNotOk }) -mkCompulsoryUnfolding :: CoreExpr -> Unfolding -mkCompulsoryUnfolding expr -- Used for things that absolutely must be unfolded - = mkCoreUnfolding InlineCompulsory True - (simpleOptExpr unsafeGlobalDynFlags expr) - (UnfWhen { ug_arity = 0 -- Arity of unfolding doesn't matter - , ug_unsat_ok = unSaturatedOk, ug_boring_ok = boringCxtOk }) - mkWorkerUnfolding :: DynFlags -> (CoreExpr -> CoreExpr) -> Unfolding -> Unfolding -- See Note [Worker-wrapper for INLINABLE functions] in GHC.Core.Op.WorkWrap mkWorkerUnfolding dflags work_fn @@ -309,20 +310,6 @@ I'm a bit worried that it's possible for the same kind of problem to arise for non-0-ary functions too, but let's wait and see. -} -mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr - -> UnfoldingGuidance -> Unfolding --- Occurrence-analyses the expression before capturing it -mkCoreUnfolding src top_lvl expr guidance - = CoreUnfolding { uf_tmpl = occurAnalyseExpr_NoBinderSwap expr, - -- See Note [Occurrence analysis of unfoldings] - uf_src = src, - uf_is_top = top_lvl, - uf_is_value = exprIsHNF expr, - uf_is_conlike = exprIsConLike expr, - uf_is_work_free = exprIsWorkFree expr, - uf_expandable = exprIsExpandable expr, - uf_guidance = guidance } - mkUnfolding :: DynFlags -> UnfoldingSource -> Bool -- Is top-level -> Bool -- Definitely a bottoming binding @@ -331,21 +318,28 @@ mkUnfolding :: DynFlags -> UnfoldingSource -> Unfolding -- Calculates unfolding guidance -- Occurrence-analyses the expression before capturing it -mkUnfolding dflags src is_top_lvl is_bottoming expr - = CoreUnfolding { uf_tmpl = occurAnalyseExpr_NoBinderSwap expr, +mkUnfolding dflags src top_lvl is_bottoming expr + = mkCoreUnfolding src top_lvl expr guidance + where + is_top_bottoming = top_lvl && is_bottoming + guidance = calcUnfoldingGuidance dflags is_top_bottoming expr + -- NB: *not* (calcUnfoldingGuidance (occurAnalyseExpr expr))! + -- See Note [Calculate unfolding guidance on the non-occ-anal'd expression] + +mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr + -> UnfoldingGuidance -> Unfolding +-- Occurrence-analyses the expression before capturing it +mkCoreUnfolding src top_lvl expr guidance + = CoreUnfolding { uf_tmpl = occurAnalyseExpr expr, -- See Note [Occurrence analysis of unfoldings] uf_src = src, - uf_is_top = is_top_lvl, + uf_is_top = top_lvl, uf_is_value = exprIsHNF expr, uf_is_conlike = exprIsConLike expr, - uf_expandable = exprIsExpandable expr, uf_is_work_free = exprIsWorkFree expr, + uf_expandable = exprIsExpandable expr, uf_guidance = guidance } - where - is_top_bottoming = is_top_lvl && is_bottoming - guidance = calcUnfoldingGuidance dflags is_top_bottoming expr - -- NB: *not* (calcUnfoldingGuidance (occurAnalyseExpr_NoBinderSwap expr))! - -- See Note [Calculate unfolding guidance on the non-occ-anal'd expression] + {- Note [Occurrence analysis of unfoldings] @@ -366,39 +360,6 @@ But more generally, the simplifier is designed on the basis that it is looking at occurrence-analysed expressions, so better ensure that they actually are. -We use occurAnalyseExpr_NoBinderSwap instead of occurAnalyseExpr; -see Note [No binder swap in unfoldings]. - -Note [No binder swap in unfoldings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The binder swap can temporarily violate Core Lint, by assigning -a LocalId binding to a GlobalId. For example, if A.foo{r872} -is a GlobalId with unique r872, then - - case A.foo{r872} of bar { - K x -> ...(A.foo{r872})... - } - -gets transformed to - - case A.foo{r872} of bar { - K x -> let foo{r872} = bar - in ...(A.foo{r872})... - -This is usually not a problem, because the simplifier will transform -this to: - - case A.foo{r872} of bar { - K x -> ...(bar)... - -However, after occurrence analysis but before simplification, this extra 'let' -violates the Core Lint invariant that we do not have local 'let' bindings for -GlobalIds. That seems (just) tolerable for the occurrence analysis that happens -just before the Simplifier, but not for unfoldings, which are Linted -independently. -As a quick workaround, we disable binder swap in this module. -See #16288 and #16296 for further plans. - Note [Calculate unfolding guidance on the non-occ-anal'd expression] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Notice that we give the non-occur-analysed expression to ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -696,7 +696,7 @@ filterAlts _tycon inst_tys imposs_cons alts impossible_alt _ _ = False -- | Refine the default alternative to a 'DataAlt', if there is a unique way to do so. --- See Note [Refine Default Alts] +-- See Note [Refine DEFAULT case alternatives] refineDefaultAlt :: [Unique] -- ^ Uniques for constructing new binders -> TyCon -- ^ Type constructor of scrutinee's type -> [Type] -- ^ Type arguments of scrutinee's type @@ -739,95 +739,62 @@ refineDefaultAlt us tycon tys imposs_deflt_cons all_alts | otherwise -- The common case = (False, all_alts) -{- Note [Refine Default Alts] - -refineDefaultAlt replaces the DEFAULT alt with a constructor if there is one -possible value it could be. +{- Note [Refine DEFAULT case alternatives] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +refineDefaultAlt replaces the DEFAULT alt with a constructor if there +is one possible value it could be. The simplest example being + foo :: () -> () + foo x = case x of !_ -> () +which rewrites to + foo :: () -> () + foo x = case x of () -> () + +There are two reasons in general why replacing a DEFAULT alternative +with a specific constructor is desirable. + +1. We can simplify inner expressions. For example + + data Foo = Foo1 () + + test :: Foo -> () + test x = case x of + DEFAULT -> mid (case x of + Foo1 x1 -> x1) + + refineDefaultAlt fills in the DEFAULT here with `Foo ip1` and then + x becomes bound to `Foo ip1` so is inlined into the other case + which causes the KnownBranch optimisation to kick in. If we don't + refine DEFAULT to `Foo ip1`, we are left with both case expressions. + +2. combineIdenticalAlts does a better job. For exapple (Simon Jacobi) + data D = C0 | C1 | C2 + + case e of + DEFAULT -> e0 + C0 -> e1 + C1 -> e1 + + When we apply combineIdenticalAlts to this expression, it can't + combine the alts for C0 and C1, as we already have a default case. + But if we apply refineDefaultAlt first, we get + case e of + C0 -> e1 + C1 -> e1 + C2 -> e0 + and combineIdenticalAlts can turn that into + case e of + DEFAULT -> e1 + C2 -> e0 -foo :: () -> () -foo x = case x of !_ -> () - -rewrites to - -foo :: () -> () -foo x = case x of () -> () - -There are two reasons in general why this is desirable. - -1. We can simplify inner expressions - -In this example we can eliminate the inner case by refining the outer case. -If we don't refine it, we are left with both case expressions. - -``` -{-# LANGUAGE BangPatterns #-} -module Test where - -mid x = x -{-# NOINLINE mid #-} - -data Foo = Foo1 () - -test :: Foo -> () -test x = - case x of - !_ -> mid (case x of - Foo1 x1 -> x1) - -``` - -refineDefaultAlt fills in the DEFAULT here with `Foo ip1` and then x -becomes bound to `Foo ip1` so is inlined into the other case which -causes the KnownBranch optimisation to kick in. - - -2. combineIdenticalAlts does a better job - -Simon Jakobi also points out that that combineIdenticalAlts will do a better job -if we refine the DEFAULT first. - -``` -data D = C0 | C1 | C2 - -case e of - DEFAULT -> e0 - C0 -> e1 - C1 -> e1 -``` - -When we apply combineIdenticalAlts to this expression, it can't -combine the alts for C0 and C1, as we already have a default case. - -If we apply refineDefaultAlt first, we get - -``` -case e of - C0 -> e1 - C1 -> e1 - C2 -> e0 -``` - -and combineIdenticalAlts can turn that into - -``` -case e of - DEFAULT -> e1 - C2 -> e0 -``` - -It isn't obvious that refineDefaultAlt does this but if you look at its one call -site in GHC.Core.Op.Simplify.Utils then the `imposs_deflt_cons` argument is -populated with constructors which are matched elsewhere. - --} - - - + It isn't obvious that refineDefaultAlt does this but if you look + at its one call site in GHC.Core.Op.Simplify.Utils then the + `imposs_deflt_cons` argument is populated with constructors which + are matched elsewhere. -{- Note [Combine identical alternatives] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Combine identical alternatives] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If several alternatives are identical, merge them into a single DEFAULT alternative. I've occasionally seen this making a big difference: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -347,10 +347,7 @@ The way we fix this is to: * In cloneBndr, drop all unfoldings/rules * In deFloatTop, run a simple dead code analyser on each top-level - RHS to drop the dead local bindings. For that call to OccAnal, we - disable the binder swap, else the occurrence analyser sometimes - introduces new let bindings for cased binders, which lead to the bug - in #5433. + RHS to drop the dead local bindings. The reason we don't just OccAnal the whole output of CorePrep is that the tidier ensures that all top-level binders are GlobalIds, so they @@ -1316,14 +1313,13 @@ deFloatTop :: Floats -> [CoreBind] deFloatTop (Floats _ floats) = foldrOL get [] floats where - get (FloatLet b) bs = occurAnalyseRHSs b : bs - get (FloatCase body var _ _ _) bs - = occurAnalyseRHSs (NonRec var body) : bs + get (FloatLet b) bs = get_bind b : bs + get (FloatCase body var _ _ _) bs = get_bind (NonRec var body) : bs get b _ = pprPanic "corePrepPgm" (ppr b) -- See Note [Dead code in CorePrep] - occurAnalyseRHSs (NonRec x e) = NonRec x (occurAnalyseExpr_NoBinderSwap e) - occurAnalyseRHSs (Rec xes) = Rec [(x, occurAnalyseExpr_NoBinderSwap e) | (x, e) <- xes] + get_bind (NonRec x e) = NonRec x (occurAnalyseExpr e) + get_bind (Rec xes) = Rec [(x, occurAnalyseExpr e) | (x, e) <- xes] --------------------------------------------------------------------------- ===================================== compiler/GHC/Iface/Tidy.hs ===================================== @@ -1239,8 +1239,7 @@ tidyTopIdInfo dflags rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold | otherwise = minimal_unfold_info minimal_unfold_info = zapUnfolding unf_info - unf_from_rhs = mkTopUnfolding dflags is_bot tidy_rhs - is_bot = isBottomingSig final_sig + unf_from_rhs = mkFinalUnfolding dflags InlineRhs final_sig tidy_rhs -- NB: do *not* expose the worker if show_unfold is off, -- because that means this thing is a loop breaker or -- marked NOINLINE or something like that ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -63,7 +63,6 @@ import GHC.Types.Name import GHC.Types.Name.Env import GHC.Types.Name.Set import GHC.Core.Op.OccurAnal ( occurAnalyseExpr ) -import GHC.Types.Demand import GHC.Types.Module import GHC.Types.Unique.FM import GHC.Types.Unique.Supply @@ -1506,14 +1505,12 @@ tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) | otherwise = InlineRhs ; return $ case mb_expr of Nothing -> NoUnfolding - Just expr -> mkUnfolding dflags unf_src - True {- Top level -} - (isBottomingSig strict_sig) - expr + Just expr -> mkFinalUnfolding dflags unf_src strict_sig expr } where -- Strictness should occur before unfolding! strict_sig = strictnessInfo info + tcUnfolding toplvl name _ _ (IfCompulsory if_expr) = do { mb_expr <- tcPragExpr True toplvl name if_expr ; return (case mb_expr of ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -92,6 +92,7 @@ import GHC.Core.DataCon import GHC.Types.Id import GHC.Stg.Syntax import Outputable +import GHC.Types.Basic (isWeakLoopBreaker) import GHC.Types.Var.Env import GHC.Core (AltCon(..)) import Data.List (mapAccumL) @@ -391,6 +392,7 @@ stgCsePairs env0 ((b,e):pairs) stgCseRhs :: CseEnv -> OutId -> InStgRhs -> (Maybe (OutId, OutStgRhs), CseEnv) stgCseRhs env bndr (StgRhsCon ccs dataCon args) | Just other_bndr <- envLookup dataCon args' env + , not (isWeakLoopBreaker (idOccInfo bndr)) -- See Note [Care with loop breakers] = let env' = addSubst bndr other_bndr env in (Nothing, env') | otherwise @@ -399,6 +401,7 @@ stgCseRhs env bndr (StgRhsCon ccs dataCon args) pair = (bndr, StgRhsCon ccs dataCon args') in (Just pair, env') where args' = substArgs env args + stgCseRhs env bndr (StgRhsClosure ext ccs upd args body) = let (env1, args') = substBndrs env args env2 = forgetCse env1 -- See note [Free variables of an StgClosure] @@ -416,6 +419,21 @@ mkStgCase scrut bndr ty alts | all isBndr alts = scrut isBndr _ = False +{- Note [Care with loop breakers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When doing CSE on a letrec we must be careful about loop +breakers. Consider + rec { y = K z + ; z = K z } +Now if, somehow (and wrongly)), y and z are both marked as +loop-breakers, we do *not* want to drop the (z = K z) binding +in favour of a substitution (z :-> y). + +I think this bug will only show up if the loop-breaker-ness is done +wrongly (itself a bug), but it still seems better to do the right +thing regardless. +-} + -- Utilities -- | This function short-cuts let-bindings that are now obsolete ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -86,7 +86,8 @@ module GHC.Types.Id.Info ( import GhcPrelude -import GHC.Core +import GHC.Core hiding( hasCoreUnfolding ) +import GHC.Core( hasCoreUnfolding ) import GHC.Core.Class import {-# SOURCE #-} PrimOp (PrimOp) @@ -567,8 +568,8 @@ zapFragileInfo info@(IdInfo { occInfo = occ, unfoldingInfo = unf }) zapFragileUnfolding :: Unfolding -> Unfolding zapFragileUnfolding unf - | isFragileUnfolding unf = noUnfolding - | otherwise = unf + | hasCoreUnfolding unf = noUnfolding + | otherwise = unf zapUnfolding :: Unfolding -> Unfolding -- Squash all unfolding info, preserving only evaluated-ness ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -42,7 +42,6 @@ module GHC.Types.Id.Make ( import GhcPrelude -import GHC.Core.Rules import TysPrim import TysWiredIn import GHC.Core.Op.ConstantFold @@ -52,7 +51,8 @@ import GHC.Core.FamInstEnv import GHC.Core.Coercion import TcType import GHC.Core.Make -import GHC.Core.Utils ( mkCast, mkDefaultCase ) +import GHC.Core.FVs ( mkRuleInfo ) +import GHC.Core.Utils ( mkCast, mkDefaultCase ) import GHC.Core.Unfold import GHC.Types.Literal import GHC.Core.TyCon ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -1,5 +1,5 @@ Simplifier ticks exhausted - When trying UnfoldingDone delta + When trying UnfoldingDone delta1 To increase the limit, use -fsimpl-tick-factor=N (default 100). If you need to increase the limit substantially, please file a @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140086 + Total ticks: 140082 ===================================== testsuite/tests/simplCore/should_compile/T17901.stdout ===================================== @@ -4,13 +4,11 @@ C -> wombat1 T17901.C = \ (@p) (wombat1 :: T -> p) (x :: T) -> case x of wild { __DEFAULT -> wombat1 wild } - (wombat2 [Occ=Once*!] :: S -> p) - SA _ [Occ=Dead] -> wombat2 wild; - SB -> wombat2 T17901.SB + Tmpl= \ (@p) (wombat2 [Occ=Once!] :: S -> p) (x [Occ=Once] :: S) -> + case x of wild [Occ=Once] { __DEFAULT -> wombat2 wild }}] = \ (@p) (wombat2 :: S -> p) (x :: S) -> case x of wild { __DEFAULT -> wombat2 wild } - (wombat3 [Occ=Once*!] :: W -> p) - WB -> wombat3 T17901.WB; - WA _ [Occ=Dead] -> wombat3 wild + Tmpl= \ (@p) (wombat3 [Occ=Once!] :: W -> p) (x [Occ=Once] :: W) -> + case x of wild [Occ=Once] { __DEFAULT -> wombat3 wild }}] = \ (@p) (wombat3 :: W -> p) (x :: W) -> case x of wild { __DEFAULT -> wombat3 wild } ===================================== testsuite/tests/simplCore/should_compile/T7360.hs ===================================== @@ -6,7 +6,7 @@ module T7360 where import GHC.List as L data Foo = Foo1 | Foo2 | Foo3 !Int - + fun1 :: Foo -> () {-# NOINLINE fun1 #-} fun1 x = case x of @@ -14,7 +14,7 @@ fun1 x = case x of Foo2 -> () Foo3 {} -> () -fun2 x = (fun1 Foo1, -- Keep -ddump-simpl output +fun2 x = (fun1 Foo1, -- Keep -ddump-simpl output -- in a predictable order case x of [] -> L.length x ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 114, types: 53, coercions: 0, joins: 0/0} + = {terms: 106, types: 47, coercions: 0, joins: 0/0} -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} T7360.$WFoo3 [InlPrag=INLINE[0]] :: Int -> Foo @@ -25,21 +25,13 @@ fun1 [InlPrag=NOINLINE] :: Foo -> () fun1 = \ (x :: Foo) -> case x of { __DEFAULT -> GHC.Tuple.() } -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} -T7360.fun5 :: () +T7360.fun4 :: () [GblId, Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] -T7360.fun5 = fun1 T7360.Foo1 +T7360.fun4 = fun1 T7360.Foo1 --- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} -T7360.fun4 :: Int -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] -T7360.fun4 = GHC.Types.I# 0# - --- RHS size: {terms: 16, types: 13, coercions: 0, joins: 0/0} +-- RHS size: {terms: 11, types: 8, coercions: 0, joins: 0/0} fun2 :: forall {a}. [a] -> ((), Int) [GblId, Arity=1, @@ -48,24 +40,18 @@ fun2 :: forall {a}. [a] -> ((), Int) Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) - Tmpl= \ (@a) (x [Occ=Once!] :: [a]) -> - (T7360.fun5, - case x of wild [Occ=Once] { - [] -> T7360.fun4; - : _ [Occ=Dead] _ [Occ=Dead] -> - case GHC.List.$wlenAcc @a wild 0# of ww2 [Occ=Once] { __DEFAULT -> - GHC.Types.I# ww2 - } + Tmpl= \ (@a) (x [Occ=Once] :: [a]) -> + (T7360.fun4, + case x of wild [Occ=Once] { __DEFAULT -> + case GHC.List.$wlenAcc @a wild 0# of ww2 [Occ=Once] { __DEFAULT -> + GHC.Types.I# ww2 + } })}] fun2 = \ (@a) (x :: [a]) -> - (T7360.fun5, - case x of wild { - [] -> T7360.fun4; - : ds ds1 -> - case GHC.List.$wlenAcc @a wild 0# of ww2 { __DEFAULT -> - GHC.Types.I# ww2 - } + (T7360.fun4, + case GHC.List.$wlenAcc @a x 0# of ww2 { __DEFAULT -> + GHC.Types.I# ww2 }) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b943b25d0786da64031ac63ddf9b4574182057bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b943b25d0786da64031ac63ddf9b4574182057bb You're receiving 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 2 05:46:49 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:46:49 -0400 Subject: [Git][ghc/ghc][master] Preserve precise exceptions in strictness analysis Message-ID: <5e857c497b87d_616776d1c7423821d0@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 5 changed files: - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Types/Demand.hs - compiler/prelude/primops.txt.pp - + testsuite/tests/stranal/should_run/T17676.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Op/Simplify/Utils.hs ===================================== @@ -56,12 +56,13 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Var import GHC.Types.Demand +import GHC.Types.Var.Set +import GHC.Types.Basic +import PrimOp import GHC.Core.Op.Simplify.Monad import GHC.Core.Type hiding( substTy ) import GHC.Core.Coercion hiding( substCo ) import GHC.Core.DataCon ( dataConWorkId, isNullaryRepDataCon ) -import GHC.Types.Var.Set -import GHC.Types.Basic import Util import OrdList ( isNilOL ) import MonadUtils @@ -500,7 +501,9 @@ mkArgInfo env fun rules n_val_args call_cont -- calls to error. But now we are more careful about -- inlining lone variables, so it's ok -- (see GHC.Core.Op.Simplify.Utils.analyseCont) - if isBotDiv result_info then + -- See Note [Precise exceptions and strictness analysis] in Demand.hs + -- for the special case on raiseIO# + if isBotDiv result_info || isPrimOpId_maybe fun == Just RaiseIOOp then map isStrictDmd demands -- Finite => result is bottom else map isStrictDmd demands ++ vanilla_stricts ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -931,6 +931,54 @@ instance Outputable Divergence where ppr Diverges = char 'b' ppr Dunno = empty +{- Note [Precise vs imprecise exceptions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +An exception is considered to be /precise/ when it is thrown by the 'raiseIO#' +primop. It follows that all other primops (such as 'raise#' or +division-by-zero) throw /imprecise/ exceptions. Note that the actual type of +the exception thrown doesn't have any impact! + +GHC undertakes some effort not to apply an optimisation that would mask a +/precise/ exception with some other source of nontermination, such as genuine +divergence or an imprecise exception, so that the user can reliably +intercept the precise exception with a catch handler before and after +optimisations. + +See also the wiki page on precise exceptions: +https://gitlab.haskell.org/ghc/ghc/wikis/exceptions/precise-exceptions +Section 5 of "Tackling the awkward squad" talks about semantic concerns. +Imprecise exceptions are actually more interesting than precise ones (which are +fairly standard) from the perspective of semantics. See the paper "A Semantics +for Imprecise Exceptions" for more details. + +Note [Precise exceptions and strictness analysis] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +raiseIO# raises a *precise* exception, in contrast to raise# which +raise an *imprecise* exception. See Note [Precise vs imprecise exceptions] +in XXXX. + +Unlike raise# (which returns botDiv), we want raiseIO# to return topDiv. +Here's why. Consider this example from #13380 (similarly #17676): + f x y | x>0 = raiseIO Exc + | y>0 = return 1 + | otherwise = return 2 +Is 'f' strict in 'y'? One might be tempted to say yes! But that plays fast and +loose with the precise exception; after optimisation, (f 42 (error "boom")) +turns from throwing the precise Exc to throwing the imprecise user error +"boom". So, the defaultDmd of raiseIO# should be lazy (topDmd), which can be +achieved by giving it divergence topDiv. + +But if it returns topDiv, the simplifier will fail to discard raiseIO#'s +continuation in + case raiseIO# x s of { (# s', r #) -> } +which we'd like to optimise to + raiseIO# x s +Temporary hack solution: special treatment for raiseIO# in +Simplifier.Utils.mkArgInfo. For the non-hack solution, see +https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses +-} + + ------------------------------------------------------------------------ -- Combined demand result -- ------------------------------------------------------------------------ ===================================== compiler/prelude/primops.txt.pp ===================================== @@ -2644,27 +2644,12 @@ primop RaiseOverflowOp "raiseOverflow#" GenPrimOp out_of_line = True has_side_effects = True --- raiseIO# needs to be a primop, because exceptions in the IO monad --- must be *precise* - we don't want the strictness analyser turning --- one kind of bottom into another, as it is allowed to do in pure code. --- --- But we *do* want to know that it returns bottom after --- being applied to two arguments, so that this function is strict in y --- f x y | x>0 = raiseIO blah --- | y>0 = return 1 --- | otherwise = return 2 --- --- TODO Check that the above notes on @f@ are valid. The function successfully --- produces an IO exception when compiled without optimization. If we analyze --- it as strict in @y@, won't we change that behavior under optimization? --- I thought the rule was that it was okay to replace one valid imprecise --- exception with another, but not to replace a precise exception with --- an imprecise one (dfeuer, 2017-03-05). - primop RaiseIOOp "raiseIO#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, b #) with - strictness = { \ _arity -> mkClosedStrictSig [topDmd, topDmd] botDiv } + -- See Note [Precise exceptions and strictness analysis] in Demand.hs + -- for why we give it topDiv + -- strictness = { \ _arity -> mkClosedStrictSig [topDmd, topDmd] topDiv } out_of_line = True has_side_effects = True ===================================== testsuite/tests/stranal/should_run/T17676.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE ScopedTypeVariables #-} +import Data.IORef +import Control.Exception +import Control.Monad + +data Exc = Exc deriving Show + +instance Exception Exc + +-- Recursive instead of NOINLINE because of #17673 +f :: Int -> Int -> IO () +f 0 x = do + let true = sum [0..4] == 10 + when true $ throwIO Exc + x `seq` return () +f n x = f (n-1) (x+1) + +main = f 1 (error "expensive computation") `catch` \(_ :: Exc) -> return () ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -19,7 +19,8 @@ test('T11076', normal, multimod_compile_and_run, ['T11076.hs', 'T11076_prim.cmm' test('T11555a', normal, compile_and_run, ['']) test('T12368', exit_code(1), compile_and_run, ['']) test('T12368a', exit_code(1), compile_and_run, ['']) -test('T13380', [expect_broken(13380), exit_code(1)], compile_and_run, ['']) +test('T13380', exit_code(1), compile_and_run, ['']) test('T14171', [expect_broken(14171), exit_code(1)], compile_and_run, ['']) test('T14290', normal, compile_and_run, ['']) test('T14285', normal, multimod_compile_and_run, ['T14285', '']) +test('T17676', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42d68364f66846969edf029f878875c10cdfe0b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42d68364f66846969edf029f878875c10cdfe0b2 You're receiving 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 2 05:47:34 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:47:34 -0400 Subject: [Git][ghc/ghc][master] Fix a pointer format string in RTS Message-ID: <5e857c769500a_61675cefcac238785c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 1 changed file: - rts/sm/GC.c Changes: ===================================== rts/sm/GC.c ===================================== @@ -1976,7 +1976,7 @@ void gcCAFs(void) // This condition identifies CAFs that have just been GC'd and // don't have static_link==3 which means they should be ignored. if ((((StgWord)(p->static_link)&STATIC_BITS) | prev_static_flag) != 3) { - debugTrace(DEBUG_gccafs, "CAF gc'd at 0x%p", p); + debugTrace(DEBUG_gccafs, "CAF gc'd at %p", p); SET_INFO((StgClosure*)p,&stg_GCD_CAF_info); // stub it if (prev == NULL) { debug_caf_list = (StgIndStatic*)p->saved_info; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a88dd11594b8d8fd20500d026e657a5f99dfdd2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a88dd11594b8d8fd20500d026e657a5f99dfdd2 You're receiving 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 2 05:48:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:48:15 -0400 Subject: [Git][ghc/ghc][master] Remove unused closure stg_IND_direct Message-ID: <5e857c9f2b9f7_61673f81cca05dd8239071a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 2 changed files: - includes/stg/MiscClosures.h - rts/StgMiscClosures.cmm Changes: ===================================== includes/stg/MiscClosures.h ===================================== @@ -90,7 +90,6 @@ RTS_RET(stg_ctoi_V); RTS_RET(stg_apply_interp); RTS_ENTRY(stg_IND); -RTS_ENTRY(stg_IND_direct); RTS_ENTRY(stg_IND_STATIC); RTS_ENTRY(stg_BLACKHOLE); RTS_ENTRY(stg_CAF_BLACKHOLE); ===================================== rts/StgMiscClosures.cmm ===================================== @@ -256,15 +256,6 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") } #endif -INFO_TABLE(stg_IND_direct,1,0,IND,"IND","IND") - (P_ node) -{ - TICK_ENT_DYN_IND(); /* tick */ - node = StgInd_indirectee(node); - TICK_ENT_VIA_NODE(); - jump %ENTRY_CODE(Sp(0)) (node); -} - INFO_TABLE(stg_IND_STATIC,1,0,IND_STATIC,"IND_STATIC","IND_STATIC") /* explicit stack */ { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5beac042b995b055a66bc16be536d9e920f6864d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5beac042b995b055a66bc16be536d9e920f6864d You're receiving 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 2 05:48:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:48:50 -0400 Subject: [Git][ghc/ghc][master] Session: Memoize stderrSupportsAnsiColors Message-ID: <5e857cc2eeb06_61673f8198ee100c2393667@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 2 changed files: - compiler/GHC/Driver/Session.hs - compiler/main/SysTools/Terminal.hs Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1253,7 +1253,6 @@ initDynFlags dflags = do `catchIOError` \_ -> return False ghcNoUnicodeEnv <- lookupEnv "GHC_NO_UNICODE" let useUnicode' = isNothing ghcNoUnicodeEnv && canUseUnicode - canUseColor <- stderrSupportsAnsiColors maybeGhcColorsEnv <- lookupEnv "GHC_COLORS" maybeGhcColoursEnv <- lookupEnv "GHC_COLOURS" let adjustCols (Just env) = Col.parseScheme env @@ -1270,7 +1269,7 @@ initDynFlags dflags = do nextWrapperNum = wrapperNum, useUnicode = useUnicode', useColor = useColor', - canUseColor = canUseColor, + canUseColor = stderrSupportsAnsiColors, colScheme = colScheme', rtldInfo = refRtldInfo, rtccInfo = refRtccInfo ===================================== compiler/main/SysTools/Terminal.hs ===================================== @@ -18,6 +18,8 @@ import qualified Graphics.Win32 as Win32 import qualified System.Win32 as Win32 #endif +import System.IO.Unsafe + #if defined(mingw32_HOST_OS) && !defined(WINAPI) # if defined(i386_HOST_ARCH) # define WINAPI stdcall @@ -28,9 +30,15 @@ import qualified System.Win32 as Win32 # endif #endif +-- | Does the controlling terminal support ANSI color sequences? +-- This memoized to avoid thread-safety issues in ncurses (see #17922). +stderrSupportsAnsiColors :: Bool +stderrSupportsAnsiColors = unsafePerformIO stderrSupportsAnsiColors' +{-# NOINLINE stderrSupportsAnsiColors #-} + -- | Check if ANSI escape sequences can be used to control color in stderr. -stderrSupportsAnsiColors :: IO Bool -stderrSupportsAnsiColors = do +stderrSupportsAnsiColors' :: IO Bool +stderrSupportsAnsiColors' = do #if defined(MIN_VERSION_terminfo) stderr_available <- queryTerminal stdError if stderr_available then View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/88f38b03025386f0f1e8f5861eed67d80495168a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/88f38b03025386f0f1e8f5861eed67d80495168a You're receiving 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 2 05:49:30 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:49:30 -0400 Subject: [Git][ghc/ghc][master] Make Hadrian build with Cabal-3.2 Message-ID: <5e857cead059b_61673f8198ee100c2397135@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 3 changed files: - hadrian/hadrian.cabal - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Library.hs Changes: ===================================== hadrian/hadrian.cabal ===================================== @@ -133,7 +133,7 @@ executable hadrian other-extensions: MultiParamTypeClasses , TypeFamilies build-depends: base >= 4.8 && < 5 - , Cabal >= 3.0 && < 3.1 + , Cabal >= 3.0 && < 3.3 , containers >= 0.5 && < 0.7 , directory >= 1.3.1.0 && < 1.4 , extra >= 1.4.7 ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Module : Hadrian.Haskell.Cabal.Parse @@ -38,6 +39,9 @@ import qualified Distribution.Text as C import qualified Distribution.Types.LocalBuildInfo as C import qualified Distribution.Types.CondTree as C import qualified Distribution.Types.MungedPackageId as C +#if MIN_VERSION_Cabal(3,2,0) +import qualified Distribution.Utils.ShortText as C +#endif import qualified Distribution.Verbosity as C import Hadrian.Expression import Hadrian.Haskell.Cabal @@ -69,7 +73,10 @@ parsePackageData pkg = do sorted = sort [ C.unPackageName p | C.Dependency p _ _ <- allDeps ] deps = nubOrd sorted \\ [name] depPkgs = catMaybes $ map findPackageByName deps - return $ PackageData name version (C.synopsis pd) (C.description pd) depPkgs gpd + return $ PackageData name version + (shortTextToString (C.synopsis pd)) + (shortTextToString (C.description pd)) + depPkgs gpd where -- Collect an overapproximation of dependencies by ignoring conditionals collectDeps :: Maybe (C.CondTree v [C.Dependency] a) -> [C.Dependency] @@ -78,6 +85,14 @@ parsePackageData pkg = do where f (C.CondBranch _ t mt) = collectDeps (Just t) ++ collectDeps mt +#if MIN_VERSION_Cabal(3,2,0) + shortTextToString :: C.ShortText -> String + shortTextToString = C.fromShortText +#else + shortTextToString :: String -> String + shortTextToString = id +#endif + -- | Parse the package identifier from a Cabal file. parseCabalPkgId :: FilePath -> IO String parseCabalPkgId file = C.display . C.package . C.packageDescription <$> C.readGenericPackageDescription C.silent file ===================================== hadrian/src/Rules/Library.hs ===================================== @@ -140,7 +140,7 @@ extraObjects context -- | Return all the object files to be put into the library we're building for -- the given 'Context'. libraryObjects :: Context -> Action [FilePath] -libraryObjects context at Context{..} = do +libraryObjects context = do hsObjs <- hsObjects context noHsObjs <- nonHsObjects context need $ noHsObjs ++ hsObjs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27740f24cb70fc14b00c1212c06642a144a6117d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27740f24cb70fc14b00c1212c06642a144a6117d You're receiving 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 2 05:50:09 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:50:09 -0400 Subject: [Git][ghc/ghc][master] Update Stack resolver for hadrian/build-stack Message-ID: <5e857d11b01a9_6167683004424002fe@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 2 changed files: - hadrian/hadrian.cabal - hadrian/stack.yaml Changes: ===================================== hadrian/hadrian.cabal ===================================== @@ -141,7 +141,7 @@ executable hadrian , mtl == 2.2.* , parsec >= 3.1 && < 3.2 , QuickCheck >= 2.6 && < 2.14 - , shake >= 0.18.3 && < 0.18.4 + , shake >= 0.18.3 && < 0.18.6 , transformers >= 0.4 && < 0.6 , unordered-containers >= 0.2.1 && < 0.3 build-tools: alex >= 3.1 ===================================== hadrian/stack.yaml ===================================== @@ -1,8 +1,4 @@ -resolver: lts-14.7 - -extra-deps: -- happy-1.19.12 -- Cabal-3.0.0.0 at sha256:1ba37b8d80e89213b17db7b8b9ea0108da55ca65f8c0cbb7433881a284c5cf67 +resolver: lts-15.5 packages: - '.' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4980200255dabf59ae537f10c55d19ef1a00bbdd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4980200255dabf59ae537f10c55d19ef1a00bbdd You're receiving 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 2 05:50:49 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 01:50:49 -0400 Subject: [Git][ghc/ghc][master] Fix two ASSERT buglets in reifyDataCon Message-ID: <5e857d39e4da9_6167120434ec24032d8@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 4 changed files: - compiler/typecheck/TcSplice.hs - + testsuite/tests/th/T17305.hs - + testsuite/tests/th/T17305.stderr - testsuite/tests/th/all.T Changes: ===================================== compiler/typecheck/TcSplice.hs ===================================== @@ -1769,7 +1769,7 @@ reifyDataCon isGadtDataCon tys dc -- constructors can be declared infix. -- See Note [Infix GADT constructors] in TcTyClsDecls. | dataConIsInfix dc && not isGadtDataCon -> - ASSERT( arg_tys `lengthIs` 2 ) do + ASSERT( r_arg_tys `lengthIs` 2 ) do { let [r_a1, r_a2] = r_arg_tys [s1, s2] = dcdBangs ; return $ TH.InfixC (s1,r_a1) name (s2,r_a2) } @@ -1788,7 +1788,7 @@ reifyDataCon isGadtDataCon tys dc { cxt <- reifyCxt theta' ; ex_tvs'' <- reifyTyVars ex_tvs' ; return (TH.ForallC ex_tvs'' cxt main_con) } - ; ASSERT( arg_tys `equalLength` dcdBangs ) + ; ASSERT( r_arg_tys `equalLength` dcdBangs ) ret_con } {- ===================================== testsuite/tests/th/T17305.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +module T17305 where + +import Data.Kind +import Language.Haskell.TH hiding (Type) +import System.IO + +data family Foo a +data instance Foo :: Type -> Type where + MkFoo :: Foo a + +$(do i <- reify ''Foo + runIO $ hPutStrLn stderr $ pprint i + pure []) ===================================== testsuite/tests/th/T17305.stderr ===================================== @@ -0,0 +1,3 @@ +data family T17305.Foo (a_0 :: *) :: * +data instance T17305.Foo where + T17305.MkFoo :: forall (a_1 :: *) . T17305.Foo a_1 ===================================== testsuite/tests/th/all.T ===================================== @@ -492,6 +492,7 @@ test('T16980a', normal, compile_fail, ['']) test('T17270a', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-v0']) test('T17270b', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-fenable-th-splice-warnings -v0']) test('T17296', normal, compile, ['-v0']) +test('T17305', normal, compile, ['-v0']) test('T17380', normal, compile_fail, ['']) test('T17394', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T17379a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/30a63e79c65b023497af4fe2347149382c71829d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/30a63e79c65b023497af4fe2347149382c71829d You're receiving 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 2 06:09:04 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 02:09:04 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sjakobi/no-applicativedo Message-ID: <5e8581809a927_616776d1c7424036c7@gitlab.haskell.org.mail> Simon Jakobi pushed new branch wip/sjakobi/no-applicativedo at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/no-applicativedo You're receiving 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 2 06:23:17 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 02:23:17 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 14 commits: Re-engineer the binder-swap transformation Message-ID: <5e8584d573588_6167665346024102ab@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 3a3aefbb by Zubin Duggal at 2020-04-02T02:22:59-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 2ce166ba by Moritz Bruder at 2020-04-02T02:23:02-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - 491c3846 by Sylvain Henry at 2020-04-02T02:23:04-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - e3681081 by Sylvain Henry at 2020-04-02T02:23:04-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - f6f871b9 by Sylvain Henry at 2020-04-02T02:23:04-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 14d8f5f3 by Maxim Koltsov at 2020-04-02T02:23:06-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf407bed46880760bb35be268651434775c0036c...14d8f5f360b195f79a04a73949d16b5861d5700e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf407bed46880760bb35be268651434775c0036c...14d8f5f360b195f79a04a73949d16b5861d5700e You're receiving 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 2 06:59:58 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 02 Apr 2020 02:59:58 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 11 commits: PmCheck: Adjust recursion depth for inhabitation test Message-ID: <5e858d6e66197_6167c5fa3c824213ce@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 1ea89aee by Ömer Sinan Ağacan at 2020-04-02T02:59:56-04:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f93466a1814b728caa264ac341c7483869331a7...1ea89aee6c64c6351efc1ae4dbffe3193a29f3d9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f93466a1814b728caa264ac341c7483869331a7...1ea89aee6c64c6351efc1ae4dbffe3193a29f3d9 You're receiving 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 2 09:22:37 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 02 Apr 2020 05:22:37 -0400 Subject: [Git][ghc/ghc][wip/T17917] 21 commits: Expect T4267 to pass Message-ID: <5e85aeddb9025_6167116c28dc2445083@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 9a18e322 by Simon Peyton Jones at 2020-04-02T10:22:14+01:00 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. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Op/WorkWrap.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Runtime/Heap/Inspect.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4b62b5c8e6815b4d0451b1cd3d4a873bd1934e3f...9a18e3220ca0ab162a9f1047479f83fb7a327bfa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4b62b5c8e6815b4d0451b1cd3d4a873bd1934e3f...9a18e3220ca0ab162a9f1047479f83fb7a327bfa You're receiving 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 2 09:52:57 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 02 Apr 2020 05:52:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/ticker Message-ID: <5e85b5f9994a7_616768300442473044@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/ticker at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/ticker You're receiving 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 2 10:03:31 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 02 Apr 2020 06:03:31 -0400 Subject: [Git][ghc/ghc][wip/andreask/ticker] 159 commits: Improve error handling for VTA + deferred type errors Message-ID: <5e85b873cc36c_61675cefcac24746f3@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/ticker at Glasgow Haskell Compiler / GHC Commits: 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 38c072c7 by Andreas Klebinger at 2020-04-02T12:03:13+02:00 Move windows RTS timers to a QueryPerformanceCounter based API. This code was initially part of WINIO and the initial version was written by Phyx (Tamar Christina). - - - - - 30 changed files: - .ghcid - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/linters/check-cpp.py - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Opt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dbc9e1eac851a4657c067f94efd31419216a144e...38c072c70de8272c009f7bb36a9cf6713afde94d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dbc9e1eac851a4657c067f94efd31419216a144e...38c072c70de8272c009f7bb36a9cf6713afde94d You're receiving 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 2 11:13:38 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 07:13:38 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] 23 commits: Clean up "Eta reduction for data families" Notes Message-ID: <5e85c8e279d8c_6167116c28dc24886c4@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ddffd7e2 by Simon Jakobi at 2020-04-02T13:07:03+02:00 Use non-deterministic strict fold instead of foldDVarSet ...which is O(n log n) - - - - - 617dca65 by Simon Jakobi at 2020-04-02T13:07:03+02:00 Delete some evidence bindings more efficiently (needs refactoring) - - - - - c9afcda1 by Simon Jakobi at 2020-04-02T13:07:03+02:00 Use non-deterministic fold to insert wanted evidence bindings - - - - - 5b983dbb by Simon Jakobi at 2020-04-02T13:07:04+02:00 Add and use evBindMapToVarSet - - - - - 9e0a1939 by Simon Jakobi at 2020-04-02T13:07:04+02:00 Improve udfmToUfm - - - - - 7bf55702 by Simon Jakobi at 2020-04-02T13:12:07+02:00 Convert some existing non-det folds to be strict - - - - - f5b34af7 by Simon Jakobi at 2020-04-02T13:13:11+02:00 Use the argument order of the deterministic folds - - - - - 95054b16 by Simon Jakobi at 2020-04-02T13:13:18+02:00 Use strict folds in GraphOps - - - - - 910233e7 by Simon Jakobi at 2020-04-02T13:13:18+02:00 Try a strict fold for closeOverKinds - - - - - 53a3ff77 by Simon Jakobi at 2020-04-02T13:13:18+02:00 Try strict fold in mk_mod_usage_info.ent_map - - - - - 30 changed files: - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Runtime/Heap/Inspect.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ebc5d3925902fd43a8e06f72a225ab15d39aa4a...53a3ff77d6fec5cf71ed0cd6bbeb40646e26234a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ebc5d3925902fd43a8e06f72a225ab15d39aa4a...53a3ff77d6fec5cf71ed0cd6bbeb40646e26234a You're receiving 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 2 11:37:17 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 07:37:17 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] 3 commits: Delete foldUniqDSet and foldDVarSet Message-ID: <5e85ce6d2543b_616776d1c74248932@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 30721598 by Simon Jakobi at 2020-04-02T13:18:57+02:00 Delete foldUniqDSet and foldDVarSet - - - - - e4d38d7c by Simon Jakobi at 2020-04-02T13:26:24+02:00 Delete nonDetFoldUDFM, nonDetFoldUFM, nonDetFoldUniqSet, ... nonDetFoldUniqSet_Directly, nonDetFoldVarSet - - - - - ebbd8260 by Simon Jakobi at 2020-04-02T13:37:03+02:00 Comments - - - - - 9 changed files: - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Set.hs Changes: ===================================== compiler/GHC/Core/Op/SetLevels.hs ===================================== @@ -1582,11 +1582,13 @@ placeJoinCeiling le@(LE { le_ctxt_lvl = lvl }) maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level maxFvLevel max_me env var_set = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet maxFvLevel' max_me env var_set = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -659,8 +659,8 @@ niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet -- This is used in the occurs check, before extending the substitution niSubstTvSet tsubst tvs = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs - -- It's OK to nonDetStrictFoldUFM here because we immediately forget the - -- ordering by creating a set. + -- It's OK to use a non-deterministic fold here because we immediately forget + -- the ordering by creating a set. where get tv | Just ty <- lookupVarEnv tsubst tv ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -1423,7 +1423,7 @@ depAnalTyClDecls rdr_env kisig_fv_env ds_w_fvs toParents :: GlobalRdrEnv -> NameSet -> NameSet toParents rdr_env ns = nonDetStrictFoldUniqSet add emptyNameSet ns - -- It's OK to use nonDetStrictFoldUFM because we immediately forget the + -- It's OK to use a non-deterministic fold because we immediately forget the -- ordering by creating a set where add n s = extendNameSet s (getParent rdr_env n) ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -546,6 +546,7 @@ closureGrowth expander sizer group abs_ids = go newbies = abs_ids `minusDVarSet` clo_fvs' -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + -- Using a non-deterministic fold is OK here because addition is commutative. go (RhsSk body_dmd body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -57,7 +57,6 @@ module GHC.Types.Unique.DFM ( udfmToList, udfmToUfm, - nonDetFoldUDFM, nonDetStrictFoldUDFM, alwaysUnsafeUfmToUdfm, ) where @@ -273,13 +272,10 @@ elemUDFM k (UDFM m _i) = M.member (getKey $ getUnique k) m foldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a foldUDFM k z m = foldr k z (eltsUDFM m) --- | Performs a nondeterministic fold over the UniqDFM. +-- | Performs a nondeterministic strict fold over the UniqDFM. -- It's O(n), same as the corresponding function on `UniqFM`. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a -nonDetFoldUDFM k z (UDFM m _i) = foldr k z $ map taggedFst $ M.elems m - nonDetStrictFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a nonDetStrictFoldUDFM k z (UDFM m _i) = foldl' k' z m where ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, - foldUniqDSet, nonDetStrictFoldUniqDSet, + nonDetStrictFoldUniqDSet, elementOfUniqDSet, filterUniqDSet, sizeUniqDSet, @@ -98,9 +98,6 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) -foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b -foldUniqDSet c n (UniqDSet s) = foldUDFM c n s - nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Types.Unique.FM ( intersectUFM_C, disjointUFM, equalKeysUFM, - nonDetFoldUFM, nonDetStrictFoldUFM, foldUFM, nonDetFoldUFM_Directly, + nonDetStrictFoldUFM, foldUFM, nonDetFoldUFM_Directly, anyUFM, allUFM, seqEltsUFM, mapUFM, mapUFM_Directly, elemUFM, elemUFM_Directly, @@ -318,9 +318,6 @@ nonDetKeysUFM (UFM m) = map getUnique $ M.keys m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM k z (UFM m) = M.foldr k z m - nonDetStrictFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -42,9 +42,7 @@ module GHC.Types.Unique.Set ( unsafeUFMToUniqSet, nonDetEltsUniqSet, nonDetKeysUniqSet, - nonDetFoldUniqSet, nonDetStrictFoldUniqSet, - nonDetFoldUniqSet_Directly ) where import GhcPrelude @@ -164,18 +162,9 @@ nonDetKeysUniqSet = nonDetKeysUFM . getUniqSet' -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet c n (UniqSet s) = nonDetFoldUFM c n s - nonDetStrictFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a nonDetStrictFoldUniqSet c n (UniqSet s) = nonDetStrictFoldUFM c n s --- See Note [Deterministic UniqFM] to learn about nondeterminism. --- If you use this please provide a justification why it doesn't introduce --- nondeterminism. -nonDetFoldUniqSet_Directly:: (Unique -> elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet_Directly f n (UniqSet s) = nonDetFoldUFM_Directly f n s - -- See Note [UniqSet invariant] mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapUniqSet f = mkUniqSet . map f . nonDetEltsUniqSet ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Types.Var.Set ( sizeVarSet, seqVarSet, elemVarSetByKey, partitionVarSet, pluralVarSet, pprVarSet, - nonDetFoldVarSet, nonDetStrictFoldVarSet, + nonDetStrictFoldVarSet, -- * Deterministic Var set types DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, @@ -37,7 +37,7 @@ module GHC.Types.Var.Set ( intersectsDVarSet, disjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, minusDVarSet, - foldDVarSet, nonDetStrictFoldDVarSet, + nonDetStrictFoldDVarSet, filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, transCloDVarSet, @@ -154,9 +154,6 @@ allVarSet = uniqSetAll mapVarSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapVarSet = mapUniqSet -nonDetFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a -nonDetFoldVarSet = nonDetFoldUniqSet - nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet @@ -295,9 +292,6 @@ minusDVarSet = minusUniqDSet dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet dVarSetMinusVarSet = uniqDSetMinusUniqSet -foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a -foldDVarSet = foldUniqDSet - nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53a3ff77d6fec5cf71ed0cd6bbeb40646e26234a...ebbd82602573a3313119b079e56ede716d93bab3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53a3ff77d6fec5cf71ed0cd6bbeb40646e26234a...ebbd82602573a3313119b079e56ede716d93bab3 You're receiving 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 2 11:55:53 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 02 Apr 2020 07:55:53 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] 20 commits: Require GHC 8.8 as the minimum compiler for bootstrapping Message-ID: <5e85d2c9cc680_6167120434ec2495549@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 9454eae1 by Sebastian Graf at 2020-04-02T13:55:15+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2a0aabe2e57ccc74bbd0801635b14f7d055e8f8...9454eae1843f99921297afef347e97af10d92ed6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2a0aabe2e57ccc74bbd0801635b14f7d055e8f8...9454eae1843f99921297afef347e97af10d92ed6 You're receiving 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 2 11:58:20 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 07:58:20 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] 2 commits: More comments Message-ID: <5e85d35cdf61e_6167116c28dc2496056@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 5a8fc542 by Simon Jakobi at 2020-04-02T13:50:35+02:00 More comments - - - - - 3e0f1411 by Simon Jakobi at 2020-04-02T13:57:17+02:00 Add references to Note [Deterministic UniqFM] - - - - - 7 changed files: - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/typecheck/TcEvidence.hs - compiler/typecheck/TcSimplify.hs - compiler/utils/GraphOps.hs Changes: ===================================== compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs ===================================== @@ -555,7 +555,8 @@ delAssoc a m | Just aSet <- lookupUFM m a , m1 <- delFromUFM m a = nonDetStrictFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet - -- It's OK to use nonDetStrictFoldUFM here because deletion is commutative + -- It's OK to use a non-deterministic fold here because deletion is + -- commutative | otherwise = m ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -98,6 +98,9 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -583,6 +583,9 @@ lookupDVarEnv = lookupUDFM foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b foldDVarEnv = foldUDFM +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. nonDetStrictFoldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b nonDetStrictFoldDVarEnv = nonDetStrictFoldUDFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -154,6 +154,9 @@ allVarSet = uniqSetAll mapVarSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapVarSet = mapUniqSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet @@ -292,6 +295,9 @@ minusDVarSet = minusUniqDSet dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet dVarSetMinusVarSet = uniqDSetMinusUniqSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet ===================================== compiler/typecheck/TcEvidence.hs ===================================== @@ -501,6 +501,9 @@ evBindMapBinds = foldEvBindMap consBag emptyBag foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. nonDetStrictFoldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a nonDetStrictFoldEvBindMap k z bs = nonDetStrictFoldDVarEnv k z (ev_bind_varenv bs) @@ -863,7 +866,7 @@ findNeededEvVars ev_binds seeds where also_needs :: VarSet -> VarSet also_needs needs = nonDetStrictFoldUniqSet add emptyVarSet needs - -- It's OK to use nonDetStrictFoldUFM here because we immediately + -- It's OK to use a non-deterministic fold here because we immediately -- forget about the ordering by creating a set add :: Var -> VarSet -> VarSet ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -1863,6 +1863,8 @@ neededEvVars implic@(Implic { ic_given = givens ; let seeds1 = foldr add_implic_seeds old_needs implics seeds2 = nonDetStrictFoldEvBindMap add_wanted seeds1 ev_binds + -- It's OK to use a non-deterministic fold here + -- because add_wanted is commutative seeds3 = seeds2 `unionVarSet` tcvs need_inner = findNeededEvVars ev_binds seeds3 live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds ===================================== compiler/utils/GraphOps.hs ===================================== @@ -64,7 +64,7 @@ addNode k node graph -- add back conflict edges from other nodes to this one map_conflict = nonDetStrictFoldUniqSet - -- It's OK to use nonDetStrictFoldUFM here because the + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeConflicts = addOneToUniqSet (nodeConflicts n) k})) @@ -74,7 +74,7 @@ addNode k node graph -- add back coalesce edges from other nodes to this one map_coalesce = nonDetStrictFoldUniqSet - -- It's OK to use nonDetStrictFoldUFM here because the + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeCoalesce = addOneToUniqSet (nodeCoalesce n) k})) @@ -477,8 +477,8 @@ freezeNode k -- If the edge isn't actually in the coelesce set then just ignore it. fm2 = nonDetStrictFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 - -- It's OK to use nonDetStrictFoldUFM here because the operation - -- is commutative + -- It's OK to use a non-deterministic fold here because the + -- operation is commutative $ nodeCoalesce node in fm2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ebbd82602573a3313119b079e56ede716d93bab3...3e0f14115156921c5bb21e239542e0ad6646e701 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ebbd82602573a3313119b079e56ede716d93bab3...3e0f14115156921c5bb21e239542e0ad6646e701 You're receiving 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 2 12:09:18 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 08:09:18 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] 2 commits: Rename intMapToUFM Message-ID: <5e85d5ee68db5_6167c5fa3c825006d5@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 560caaf0 by Simon Jakobi at 2020-04-02T14:01:45+02:00 Rename intMapToUFM - - - - - e3e80611 by Simon Jakobi at 2020-04-02T14:08:58+02:00 Move varSetMinEvBindmap to a better location - - - - - 4 changed files: - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/FM.hs - compiler/typecheck/TcEvidence.hs - compiler/typecheck/TcSimplify.hs Changes: ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -72,7 +72,7 @@ import Data.Functor.Classes (Eq1 (..)) import Data.List (sortBy) import Data.Function (on) import qualified Data.Semigroup as Semi -import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, intMapToUFM) +import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM) -- Note [Deterministic UniqFM] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -340,7 +340,7 @@ udfmMinusUFM (UDFM x i) y = UDFM (M.difference x (ufmToIntMap y)) i -- bound. ufmMinusUDFM :: UniqFM elt1 -> UniqDFM elt2 -> UniqFM elt1 -ufmMinusUDFM x (UDFM y _i) = intMapToUFM (M.difference (ufmToIntMap x) y) +ufmMinusUDFM x (UDFM y _i) = unsafeIntMapToUFM (M.difference (ufmToIntMap x) y) -- | Partition UniqDFM into two UniqDFMs according to the predicate partitionUDFM :: (elt -> Bool) -> UniqDFM elt -> (UniqDFM elt, UniqDFM elt) @@ -354,7 +354,7 @@ delListFromUDFM = foldl' delFromUDFM -- | This allows for lossy conversion from UniqDFM to UniqFM udfmToUfm :: UniqDFM elt -> UniqFM elt -udfmToUfm (UDFM m _i) = intMapToUFM (M.map taggedFst m) +udfmToUfm (UDFM m _i) = unsafeIntMapToUFM (M.map taggedFst m) listToUDFM :: Uniquable key => [(key,elt)] -> UniqDFM elt listToUDFM = foldl' (\m (k, v) -> addToUDFM m k v) emptyUDFM ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -67,7 +67,7 @@ module GHC.Types.Unique.FM ( lookupWithDefaultUFM, lookupWithDefaultUFM_Directly, nonDetEltsUFM, eltsUFM, nonDetKeysUFM, ufmToSet_Directly, - nonDetUFMToList, ufmToIntMap, intMapToUFM, + nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM, pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM ) where @@ -359,8 +359,8 @@ instance Traversable NonDetUniqFM where ufmToIntMap :: UniqFM elt -> M.IntMap elt ufmToIntMap (UFM m) = m -intMapToUFM :: M.IntMap elt -> UniqFM elt -intMapToUFM = UFM +unsafeIntMapToUFM :: M.IntMap elt -> UniqFM elt +unsafeIntMapToUFM = UFM -- Determines whether two 'UniqFM's contain the same keys. equalKeysUFM :: UniqFM a -> UniqFM b -> Bool ===================================== compiler/typecheck/TcEvidence.hs ===================================== @@ -20,6 +20,7 @@ module TcEvidence ( filterEvBindMap, isEmptyEvBindMap, evBindMapToVarSet, + varSetMinusEvBindMap, EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, evBindVar, isCoEvBindsVar, @@ -514,6 +515,9 @@ filterEvBindMap k (EvBindMap { ev_bind_varenv = env }) evBindMapToVarSet :: EvBindMap -> VarSet evBindMapToVarSet (EvBindMap dve) = unsafeUFMToUniqSet (mapUFM evBindVar (udfmToUfm dve)) +varSetMinusEvBindMap :: VarSet -> EvBindMap -> VarSet +varSetMinusEvBindMap vs (EvBindMap dve) = vs `uniqSetMinusUDFM` dve + instance Outputable EvBindMap where ppr (EvBindMap m) = ppr m ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -1892,9 +1892,6 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = ev_var `elemVarSet` needed | otherwise = True -- Keep all wanted bindings - varSetMinusEvBindMap :: VarSet -> EvBindMap -> VarSet - varSetMinusEvBindMap vs ebm = uniqSetMinusUDFM vs (ev_bind_varenv ebm) - add_wanted :: EvBind -> VarSet -> VarSet add_wanted (EvBind { eb_is_given = is_given, eb_rhs = rhs }) needs | is_given = needs -- Add the rhs vars of the Wanted bindings only View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3e0f14115156921c5bb21e239542e0ad6646e701...e3e80611a705aad258c4da9cc200caee66f063c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3e0f14115156921c5bb21e239542e0ad6646e701...e3e80611a705aad258c4da9cc200caee66f063c9 You're receiving 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 2 12:45:52 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 02 Apr 2020 08:45:52 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17151 Message-ID: <5e85de806a6f7_6167bbed89425046ce@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T17151 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17151 You're receiving 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 2 13:15:08 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 09:15:08 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] Use a strict fold in splitFVs Message-ID: <5e85e55c12bbd_6167c5fa3c825136dd@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: fe485655 by Simon Jakobi at 2020-04-02T15:14:51+02:00 Use a strict fold in splitFVs - - - - - 2 changed files: - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Unique/FM.hs Changes: ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -785,16 +785,23 @@ cleanUseDmd_maybe _ = Nothing splitFVs :: Bool -- Thunk -> DmdEnv -> (DmdEnv, DmdEnv) splitFVs is_thunk rhs_fvs - | is_thunk = nonDetFoldUFM_Directly add (emptyVarEnv, emptyVarEnv) rhs_fvs - -- It's OK to use nonDetFoldUFM_Directly because we + | is_thunk = strictPairToTuple $ + nonDetStrictFoldUFM_Directly add (emptyVarEnv :*: emptyVarEnv) rhs_fvs + -- It's OK to use a non-deterministic fold because we -- immediately forget the ordering by putting the elements -- in the envs again | otherwise = partitionVarEnv isWeakDmd rhs_fvs where - add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv, sig_fv) - | Lazy <- s = (addToUFM_Directly lazy_fv uniq dmd, sig_fv) - | otherwise = ( addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) - , addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) ) + add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv :*: sig_fv) + | Lazy <- s = addToUFM_Directly lazy_fv uniq dmd :*: sig_fv + | otherwise = addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) + :*: + addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) + +data StrictPair a b = !a :*: !b + +strictPairToTuple :: StrictPair a b -> (a, b) +strictPairToTuple (x :*: y) = (x, y) data TypeShape = TsFun TypeShape | TsProd [TypeShape] ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Types.Unique.FM ( intersectUFM_C, disjointUFM, equalKeysUFM, - nonDetStrictFoldUFM, foldUFM, nonDetFoldUFM_Directly, + nonDetStrictFoldUFM, foldUFM, nonDetStrictFoldUFM_Directly, anyUFM, allUFM, seqEltsUFM, mapUFM, mapUFM_Directly, elemUFM, elemUFM_Directly, @@ -324,8 +324,8 @@ nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM_Directly k z (UFM m) = M.foldrWithKey (k . getUnique) z m +nonDetStrictFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (getUnique i) x z') z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe485655061199c09f1a81239738de74811fab36 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe485655061199c09f1a81239738de74811fab36 You're receiving 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 2 13:20:52 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 02 Apr 2020 09:20:52 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/ticker_comments Message-ID: <5e85e6b4a8538_616766534602515467@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/ticker_comments at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/ticker_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 Thu Apr 2 15:06:30 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 02 Apr 2020 11:06:30 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] 11 commits: PmCheck: Adjust recursion depth for inhabitation test Message-ID: <5e85ff76b63_6167c5fa3c8255139e@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - dc1947d8 by Andreas Klebinger at 2020-04-02T17:06:10+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. We optimize `elem` now in more ways than before. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks. These ultimately simply to a single case expression. It will also turn into a fold for dynamic lists when list fusion applies. This logic however does not work on string literals. For this reason I added a rule to do the transformation into a case explicitly via a built in rule. It will fire for any short string literals. (<=32 Bytes). Longer calls to elem on string literals are rewritten to calls to elem variants specialized to string literals. This means we will rewrite: * c `elem` (unpackCString "Foo"#) => elemCString# c' "Foo"# * c `elem` (unpackCStringUtf8 "Bär"#) => elemCStringUtf8# c' "Bär"# This means all calls to elem on string literals, as well as many on other statically known lists should now be allocation free. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors. A version of `elem` operating on known string literals was added: * elemCString# :: Char# -> Addr# -> Bool * elemCStringUtf8# :: Char# -> Addr# -> Bool - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/main/SysTools/Terminal.hs - compiler/prelude/PrelNames.hs - compiler/prelude/primops.txt.pp - compiler/typecheck/TcSplice.hs - compiler/utils/Util.hs - hadrian/hadrian.cabal - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Library.hs - hadrian/src/Settings/Builders/Ghc.hs - hadrian/stack.yaml The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6c0da2267233daddc6d2f96013ec1394bf588e4...dc1947d809f373aae48e99d0411d2c5de62202b3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6c0da2267233daddc6d2f96013ec1394bf588e4...dc1947d809f373aae48e99d0411d2c5de62202b3 You're receiving 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 2 16:04:06 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 02 Apr 2020 12:04:06 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] DmdAnal: Reflect precise exceptions in demand types Message-ID: <5e860cf682ca3_6167665346025639fb@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 24c249e7 by Sebastian Graf at 2020-04-02T18:03:48+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24c249e7cc8f7bef194244dc44e028e0045da835 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24c249e7cc8f7bef194244dc44e028e0045da835 You're receiving 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 2 16:44:12 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 12:44:12 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e86165cc8158_6167116c28dc2581839@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3eee6d7d by Zubin Duggal at 2020-04-02T12:43:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 7b976f7e by Andreas Klebinger at 2020-04-02T12:43:56-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - 43973bd6 by Moritz Bruder at 2020-04-02T12:43:57-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - aa86107a by Sylvain Henry at 2020-04-02T12:43:59-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - ed63ae22 by Sylvain Henry at 2020-04-02T12:43:59-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - 6e3d0cb1 by Sylvain Henry at 2020-04-02T12:43:59-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - bb413155 by Maxim Koltsov at 2020-04-02T12:44:01-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 026dcb5d by Andreas Klebinger at 2020-04-02T12:44:02-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 0465a64d by Simon Peyton Jones at 2020-04-02T12:44:02-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Iface/Ext/Debug.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/14d8f5f360b195f79a04a73949d16b5861d5700e...0465a64d798cc8913325f571445a3d7504f2d92e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/14d8f5f360b195f79a04a73949d16b5861d5700e...0465a64d798cc8913325f571445a3d7504f2d92e You're receiving 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 2 17:08:44 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 13:08:44 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] Improve some folds over Uniq[D]FM Message-ID: <5e861c1ca72f7_6167665346026047a3@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: de97951b by Simon Jakobi at 2020-04-02T19:02:44+02:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 21 changed files: - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/typecheck/TcEvidence.hs - compiler/typecheck/TcSimplify.hs - compiler/typecheck/TcType.hs - compiler/utils/GraphOps.hs Changes: ===================================== compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs ===================================== @@ -554,8 +554,9 @@ delAssoc :: (Uniquable a) delAssoc a m | Just aSet <- lookupUFM m a , m1 <- delFromUFM m a - = nonDetFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet - -- It's OK to use nonDetFoldUFM here because deletion is commutative + = nonDetStrictFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet + -- It's OK to use a non-deterministic fold here because deletion is + -- commutative | otherwise = m ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -380,8 +380,8 @@ famInstEnvElts fi = [elt | FamIE elts <- eltsUDFM fi, elt <- elts] -- See Note [FamInstEnv determinism] famInstEnvSize :: FamInstEnv -> Int -famInstEnvSize = nonDetFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 - -- It's OK to use nonDetFoldUDFM here since we're just computing the +famInstEnvSize = nonDetStrictFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 + -- It's OK to use nonDetStrictFoldUDFM here since we're just computing the -- size. familyInstances :: (FamInstEnv, FamInstEnv) -> TyCon -> [FamInst] ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -2243,8 +2243,8 @@ extendFvs env s = (s `unionVarSet` extras, extras `subVarSet` s) where extras :: VarSet -- env(s) - extras = nonDetFoldUFM unionVarSet emptyVarSet $ - -- It's OK to use nonDetFoldUFM here because unionVarSet commutes + extras = nonDetStrictFoldUFM unionVarSet emptyVarSet $ + -- It's OK to use nonDetStrictFoldUFM here because unionVarSet commutes intersectUFM_C (\x _ -> x) env (getUniqSet s) {- @@ -2565,8 +2565,8 @@ addManyOcc v u | isId v = addManyOccId u v -- (Same goes for INLINE.) addManyOccs :: UsageDetails -> VarSet -> UsageDetails -addManyOccs usage id_set = nonDetFoldUniqSet addManyOcc usage id_set - -- It's OK to use nonDetFoldUFM here because addManyOcc commutes +addManyOccs usage id_set = nonDetStrictFoldUniqSet addManyOcc usage id_set + -- It's OK to use nonDetStrictFoldUniqSet here because addManyOcc commutes delDetails :: UsageDetails -> Id -> UsageDetails delDetails ud bndr ===================================== compiler/GHC/Core/Op/SetLevels.hs ===================================== @@ -83,7 +83,7 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Var import GHC.Types.Var.Set -import GHC.Types.Unique.Set ( nonDetFoldUniqSet ) +import GHC.Types.Unique.Set ( nonDetStrictFoldUniqSet ) import GHC.Types.Unique.DSet ( getUniqDSet ) import GHC.Types.Var.Env import GHC.Types.Literal ( litIsTrivial ) @@ -1469,8 +1469,8 @@ isFunction (_, AnnLam b e) | isId b = True isFunction _ = False countFreeIds :: DVarSet -> Int -countFreeIds = nonDetFoldUDFM add 0 . getUniqDSet - -- It's OK to use nonDetFoldUDFM here because we're just counting things. +countFreeIds = nonDetStrictFoldUDFM add 0 . getUniqDSet + -- It's OK to use nonDetStrictFoldUDFM here because we're just counting things. where add :: Var -> Int -> Int add v n | isId v = n+1 @@ -1581,12 +1581,14 @@ placeJoinCeiling le@(LE { le_ctxt_lvl = lvl }) maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level maxFvLevel max_me env var_set - = foldDVarSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet maxFvLevel' max_me env var_set - = nonDetFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -2177,8 +2177,8 @@ unionCallInfoSet (CIS f calls1) (CIS _ calls2) = callDetailsFVs :: CallDetails -> VarSet callDetailsFVs calls = - nonDetFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls - -- It's OK to use nonDetFoldUDFM here because we forget the ordering + nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls + -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering -- immediately by converting to a nondeterministic set. callInfoFVs :: CallInfoSet -> VarSet ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -441,7 +441,7 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView closeOverKinds :: TyCoVarSet -> TyCoVarSet -- For each element of the input set, -- add the deep free variables of its kind -closeOverKinds vs = nonDetFoldVarSet do_one vs vs +closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs where do_one v acc = appEndo (deep_ty (varType v)) acc ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -658,9 +658,9 @@ niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet -- remembering that the substitution isn't necessarily idempotent -- This is used in the occurs check, before extending the substitution niSubstTvSet tsubst tvs - = nonDetFoldUniqSet (unionVarSet . get) emptyVarSet tvs - -- It's OK to nonDetFoldUFM here because we immediately forget the - -- ordering by creating a set. + = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs + -- It's OK to use a non-deterministic fold here because we immediately forget + -- the ordering by creating a set. where get tv | Just ty <- lookupVarEnv tsubst tv ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -260,9 +260,9 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names -- ent_map groups together all the things imported and used -- from a particular module ent_map :: ModuleEnv [OccName] - ent_map = nonDetFoldUniqSet add_mv emptyModuleEnv used_names - -- nonDetFoldUFM is OK here. If you follow the logic, we sort by OccName - -- in ent_hashs + ent_map = nonDetStrictFoldUniqSet add_mv emptyModuleEnv used_names + -- nonDetStrictFoldUniqSet is OK here. If you follow the logic, we sort by + -- OccName in ent_hashs where add_mv name mv_map | isWiredInName name = mv_map -- ignore wired-in names ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -1422,8 +1422,8 @@ depAnalTyClDecls rdr_env kisig_fv_env ds_w_fvs toParents :: GlobalRdrEnv -> NameSet -> NameSet toParents rdr_env ns - = nonDetFoldUniqSet add emptyNameSet ns - -- It's OK to use nonDetFoldUFM because we immediately forget the + = nonDetStrictFoldUniqSet add emptyNameSet ns + -- It's OK to use a non-deterministic fold because we immediately forget the -- ordering by creating a set where add n s = extendNameSet s (getParent rdr_env n) ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -545,7 +545,8 @@ closureGrowth expander sizer group abs_ids = go -- we lift @f@ newbies = abs_ids `minusDVarSet` clo_fvs' -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ - cost = foldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + -- Using a non-deterministic fold is OK here because addition is commutative. go (RhsSk body_dmd body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -785,16 +785,23 @@ cleanUseDmd_maybe _ = Nothing splitFVs :: Bool -- Thunk -> DmdEnv -> (DmdEnv, DmdEnv) splitFVs is_thunk rhs_fvs - | is_thunk = nonDetFoldUFM_Directly add (emptyVarEnv, emptyVarEnv) rhs_fvs - -- It's OK to use nonDetFoldUFM_Directly because we + | is_thunk = strictPairToTuple $ + nonDetStrictFoldUFM_Directly add (emptyVarEnv :*: emptyVarEnv) rhs_fvs + -- It's OK to use a non-deterministic fold because we -- immediately forget the ordering by putting the elements -- in the envs again | otherwise = partitionVarEnv isWeakDmd rhs_fvs where - add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv, sig_fv) - | Lazy <- s = (addToUFM_Directly lazy_fv uniq dmd, sig_fv) - | otherwise = ( addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) - , addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) ) + add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv :*: sig_fv) + | Lazy <- s = addToUFM_Directly lazy_fv uniq dmd :*: sig_fv + | otherwise = addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) + :*: + addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) + +data StrictPair a b = !a :*: !b + +strictPairToTuple :: StrictPair a b -> (a, b) +strictPairToTuple (x :*: y) = (x, y) data TypeShape = TsFun TypeShape | TsProd [TypeShape] ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -50,14 +50,14 @@ module GHC.Types.Unique.DFM ( equalKeysUDFM, minusUDFM, listToUDFM, - udfmMinusUFM, + udfmMinusUFM, ufmMinusUDFM, partitionUDFM, anyUDFM, allUDFM, pprUniqDFM, pprUDFM, udfmToList, udfmToUfm, - nonDetFoldUDFM, + nonDetStrictFoldUDFM, alwaysUnsafeUfmToUdfm, ) where @@ -72,7 +72,7 @@ import Data.Functor.Classes (Eq1 (..)) import Data.List (sortBy) import Data.Function (on) import qualified Data.Semigroup as Semi -import GHC.Types.Unique.FM (UniqFM, listToUFM_Directly, nonDetUFMToList, ufmToIntMap) +import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM) -- Note [Deterministic UniqFM] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -272,12 +272,14 @@ elemUDFM k (UDFM m _i) = M.member (getKey $ getUnique k) m foldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a foldUDFM k z m = foldr k z (eltsUDFM m) --- | Performs a nondeterministic fold over the UniqDFM. +-- | Performs a nondeterministic strict fold over the UniqDFM. -- It's O(n), same as the corresponding function on `UniqFM`. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a -nonDetFoldUDFM k z (UDFM m _i) = foldr k z $ map taggedFst $ M.elems m +nonDetStrictFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a +nonDetStrictFoldUDFM k z (UDFM m _i) = foldl' k' z m + where + k' acc (TaggedVal v _) = k v acc eltsUDFM :: UniqDFM elt -> [elt] eltsUDFM (UDFM m _i) = @@ -337,6 +339,9 @@ udfmMinusUFM (UDFM x i) y = UDFM (M.difference x (ufmToIntMap y)) i -- M.difference returns a subset of a left set, so `i` is a good upper -- bound. +ufmMinusUDFM :: UniqFM elt1 -> UniqDFM elt2 -> UniqFM elt1 +ufmMinusUDFM x (UDFM y _i) = unsafeIntMapToUFM (M.difference (ufmToIntMap x) y) + -- | Partition UniqDFM into two UniqDFMs according to the predicate partitionUDFM :: (elt -> Bool) -> UniqDFM elt -> (UniqDFM elt, UniqDFM elt) partitionUDFM p (UDFM m i) = @@ -349,8 +354,7 @@ delListFromUDFM = foldl' delFromUDFM -- | This allows for lossy conversion from UniqDFM to UniqFM udfmToUfm :: UniqDFM elt -> UniqFM elt -udfmToUfm (UDFM m _i) = - listToUFM_Directly [(getUnique k, taggedFst tv) | (k, tv) <- M.toList m] +udfmToUfm (UDFM m _i) = unsafeIntMapToUFM (M.map taggedFst m) listToUDFM :: Uniquable key => [(key,elt)] -> UniqDFM elt listToUDFM = foldl' (\m (k, v) -> addToUDFM m k v) emptyUDFM ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, - foldUniqDSet, + nonDetStrictFoldUniqDSet, elementOfUniqDSet, filterUniqDSet, sizeUniqDSet, @@ -98,8 +98,11 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) -foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b -foldUniqDSet c n (UniqDSet s) = foldUDFM c n s +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b +nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s elementOfUniqDSet :: Uniquable a => a -> UniqDSet a -> Bool elementOfUniqDSet k = elemUDFM k . getUniqDSet ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Types.Unique.FM ( intersectUFM_C, disjointUFM, equalKeysUFM, - nonDetFoldUFM, foldUFM, nonDetFoldUFM_Directly, + nonDetStrictFoldUFM, foldUFM, nonDetStrictFoldUFM_Directly, anyUFM, allUFM, seqEltsUFM, mapUFM, mapUFM_Directly, elemUFM, elemUFM_Directly, @@ -67,7 +67,7 @@ module GHC.Types.Unique.FM ( lookupWithDefaultUFM, lookupWithDefaultUFM_Directly, nonDetEltsUFM, eltsUFM, nonDetKeysUFM, ufmToSet_Directly, - nonDetUFMToList, ufmToIntMap, + nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM, pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM ) where @@ -318,14 +318,14 @@ nonDetKeysUFM (UFM m) = map getUnique $ M.keys m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM k z (UFM m) = M.foldr k z m +nonDetStrictFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM_Directly k z (UFM m) = M.foldrWithKey (k . getUnique) z m +nonDetStrictFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (getUnique i) x z') z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce @@ -359,6 +359,9 @@ instance Traversable NonDetUniqFM where ufmToIntMap :: UniqFM elt -> M.IntMap elt ufmToIntMap (UFM m) = m +unsafeIntMapToUFM :: M.IntMap elt -> UniqFM elt +unsafeIntMapToUFM = UFM + -- Determines whether two 'UniqFM's contain the same keys. equalKeysUFM :: UniqFM a -> UniqFM b -> Bool equalKeysUFM (UFM m1) (UFM m2) = liftEq (\_ _ -> True) m1 m2 ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -25,7 +25,7 @@ module GHC.Types.Unique.Set ( delOneFromUniqSet, delOneFromUniqSet_Directly, delListFromUniqSet, delListFromUniqSet_Directly, unionUniqSets, unionManyUniqSets, - minusUniqSet, uniqSetMinusUFM, + minusUniqSet, uniqSetMinusUFM, uniqSetMinusUDFM, intersectUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, @@ -42,12 +42,12 @@ module GHC.Types.Unique.Set ( unsafeUFMToUniqSet, nonDetEltsUniqSet, nonDetKeysUniqSet, - nonDetFoldUniqSet, - nonDetFoldUniqSet_Directly + nonDetStrictFoldUniqSet, ) where import GhcPrelude +import GHC.Types.Unique.DFM import GHC.Types.Unique.FM import GHC.Types.Unique import Data.Coerce @@ -111,6 +111,9 @@ restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) uniqSetMinusUFM :: UniqSet a -> UniqFM b -> UniqSet a uniqSetMinusUFM (UniqSet s) t = UniqSet (minusUFM s t) +uniqSetMinusUDFM :: UniqSet a -> UniqDFM b -> UniqSet a +uniqSetMinusUDFM (UniqSet s) t = UniqSet (ufmMinusUDFM s t) + elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool elementOfUniqSet a (UniqSet s) = elemUFM a s @@ -159,14 +162,8 @@ nonDetKeysUniqSet = nonDetKeysUFM . getUniqSet' -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet c n (UniqSet s) = nonDetFoldUFM c n s - --- See Note [Deterministic UniqFM] to learn about nondeterminism. --- If you use this please provide a justification why it doesn't introduce --- nondeterminism. -nonDetFoldUniqSet_Directly:: (Unique -> elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet_Directly f n (UniqSet s) = nonDetFoldUFM_Directly f n s +nonDetStrictFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a +nonDetStrictFoldUniqSet c n (UniqSet s) = nonDetStrictFoldUFM c n s -- See Note [UniqSet invariant] mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Types.Var.Env ( extendDVarEnv, extendDVarEnv_C, extendDVarEnvList, lookupDVarEnv, elemDVarEnv, - isEmptyDVarEnv, foldDVarEnv, + isEmptyDVarEnv, foldDVarEnv, nonDetStrictFoldDVarEnv, mapDVarEnv, filterDVarEnv, modifyDVarEnv, alterDVarEnv, @@ -583,6 +583,12 @@ lookupDVarEnv = lookupUDFM foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b foldDVarEnv = foldUDFM +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b +nonDetStrictFoldDVarEnv = nonDetStrictFoldUDFM + mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b mapDVarEnv = mapUDFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Types.Var.Set ( sizeVarSet, seqVarSet, elemVarSetByKey, partitionVarSet, pluralVarSet, pprVarSet, - nonDetFoldVarSet, + nonDetStrictFoldVarSet, -- * Deterministic Var set types DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, @@ -36,7 +36,9 @@ module GHC.Types.Var.Set ( intersectDVarSet, dVarSetIntersectVarSet, intersectsDVarSet, disjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, - minusDVarSet, foldDVarSet, filterDVarSet, mapDVarSet, + minusDVarSet, + nonDetStrictFoldDVarSet, + filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, transCloDVarSet, sizeDVarSet, seqDVarSet, @@ -152,8 +154,11 @@ allVarSet = uniqSetAll mapVarSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapVarSet = mapUniqSet -nonDetFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a -nonDetFoldVarSet = nonDetFoldUniqSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a +nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet fixVarSet :: (VarSet -> VarSet) -- Map the current set to a new set -> VarSet -> VarSet @@ -290,8 +295,11 @@ minusDVarSet = minusUniqDSet dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet dVarSetMinusVarSet = uniqDSetMinusUniqSet -foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a -foldDVarSet = foldUniqDSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a +nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet anyDVarSet :: (Var -> Bool) -> DVarSet -> Bool anyDVarSet p = anyUDFM p . getUniqDSet ===================================== compiler/typecheck/TcEvidence.hs ===================================== @@ -15,8 +15,12 @@ module TcEvidence ( -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), EvBindMap(..), emptyEvBindMap, extendEvBinds, - lookupEvBind, evBindMapBinds, foldEvBindMap, filterEvBindMap, + lookupEvBind, evBindMapBinds, + foldEvBindMap, nonDetStrictFoldEvBindMap, + filterEvBindMap, isEmptyEvBindMap, + evBindMapToVarSet, + varSetMinusEvBindMap, EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, evBindVar, isCoEvBindsVar, @@ -55,6 +59,8 @@ module TcEvidence ( import GhcPrelude +import GHC.Types.Unique.DFM +import GHC.Types.Unique.FM import GHC.Types.Var import GHC.Core.Coercion.Axiom import GHC.Core.Coercion @@ -496,10 +502,22 @@ evBindMapBinds = foldEvBindMap consBag emptyBag foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a +nonDetStrictFoldEvBindMap k z bs = nonDetStrictFoldDVarEnv k z (ev_bind_varenv bs) + filterEvBindMap :: (EvBind -> Bool) -> EvBindMap -> EvBindMap filterEvBindMap k (EvBindMap { ev_bind_varenv = env }) = EvBindMap { ev_bind_varenv = filterDVarEnv k env } +evBindMapToVarSet :: EvBindMap -> VarSet +evBindMapToVarSet (EvBindMap dve) = unsafeUFMToUniqSet (mapUFM evBindVar (udfmToUfm dve)) + +varSetMinusEvBindMap :: VarSet -> EvBindMap -> VarSet +varSetMinusEvBindMap vs (EvBindMap dve) = vs `uniqSetMinusUDFM` dve + instance Outputable EvBindMap where ppr (EvBindMap m) = ppr m @@ -851,8 +869,8 @@ findNeededEvVars ev_binds seeds = transCloVarSet also_needs seeds where also_needs :: VarSet -> VarSet - also_needs needs = nonDetFoldUniqSet add emptyVarSet needs - -- It's OK to use nonDetFoldUFM here because we immediately + also_needs needs = nonDetStrictFoldUniqSet add emptyVarSet needs + -- It's OK to use a non-deterministic fold here because we immediately -- forget about the ordering by creating a set add :: Var -> VarSet -> VarSet ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -1862,11 +1862,13 @@ neededEvVars implic@(Implic { ic_given = givens ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var ; let seeds1 = foldr add_implic_seeds old_needs implics - seeds2 = foldEvBindMap add_wanted seeds1 ev_binds + seeds2 = nonDetStrictFoldEvBindMap add_wanted seeds1 ev_binds + -- It's OK to use a non-deterministic fold here + -- because add_wanted is commutative seeds3 = seeds2 `unionVarSet` tcvs need_inner = findNeededEvVars ev_binds seeds3 live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds - need_outer = foldEvBindMap del_ev_bndr need_inner live_ev_binds + need_outer = varSetMinusEvBindMap need_inner live_ev_binds `delVarSetList` givens ; TcS.setTcEvBindsMap ev_binds_var live_ev_binds @@ -1890,9 +1892,6 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = ev_var `elemVarSet` needed | otherwise = True -- Keep all wanted bindings - del_ev_bndr :: EvBind -> VarSet -> VarSet - del_ev_bndr (EvBind { eb_lhs = v }) needs = delVarSet needs v - add_wanted :: EvBind -> VarSet -> VarSet add_wanted (EvBind { eb_is_given = is_given, eb_rhs = rhs }) needs | is_given = needs -- Add the rhs vars of the Wanted bindings only @@ -2381,7 +2380,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs seed_skols = mkVarSet skols `unionVarSet` mkVarSet given_ids `unionVarSet` foldr add_non_flt_ct emptyVarSet no_float_cts `unionVarSet` - foldEvBindMap add_one_bind emptyVarSet binds + evBindMapToVarSet binds -- seed_skols: See Note [What prevents a constraint from floating] (1,2,3) -- Include the EvIds of any non-floating constraints @@ -2406,9 +2405,6 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs ; return ( flt_eqs, wanteds { wc_simple = remaining_simples } ) } where - add_one_bind :: EvBind -> VarSet -> VarSet - add_one_bind bind acc = extendVarSet acc (evBindVar bind) - add_non_flt_ct :: Ct -> VarSet -> VarSet add_non_flt_ct ct acc | isDerivedCt ct = acc | otherwise = extendVarSet acc (ctEvId ct) ===================================== compiler/typecheck/TcType.hs ===================================== @@ -703,7 +703,9 @@ tcTyVarLevel tv tcTypeLevel :: TcType -> TcLevel -- Max level of any free var of the type tcTypeLevel ty - = foldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + = nonDetStrictFoldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + -- It's safe to use a non-deterministic fold because `maxTcLevel` is + -- commutative. where add v lvl | isTcTyVar v = lvl `maxTcLevel` tcTyVarLevel v ===================================== compiler/utils/GraphOps.hs ===================================== @@ -63,8 +63,8 @@ addNode k node graph = let -- add back conflict edges from other nodes to this one map_conflict = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeConflicts = addOneToUniqSet (nodeConflicts n) k})) @@ -73,8 +73,8 @@ addNode k node graph -- add back coalesce edges from other nodes to this one map_coalesce = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeCoalesce = addOneToUniqSet (nodeCoalesce n) k})) @@ -476,9 +476,9 @@ freezeNode k else node -- panic "GraphOps.freezeNode: edge to freeze wasn't in the coalesce set" -- If the edge isn't actually in the coelesce set then just ignore it. - fm2 = nonDetFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 - -- It's OK to use nonDetFoldUFM here because the operation - -- is commutative + fm2 = nonDetStrictFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 + -- It's OK to use a non-deterministic fold here because the + -- operation is commutative $ nodeCoalesce node in fm2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de97951b8140959a863ecbc55f3d0fffe5464e0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de97951b8140959a863ecbc55f3d0fffe5464e0a You're receiving 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 2 17:13:18 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 13:13:18 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] Improve some folds over Uniq[D]FM Message-ID: <5e861d2e2087_616776d1c74260784@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 140fadd3 by Simon Jakobi at 2020-04-02T19:12:37+02:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 21 changed files: - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/typecheck/TcEvidence.hs - compiler/typecheck/TcSimplify.hs - compiler/typecheck/TcType.hs - compiler/utils/GraphOps.hs Changes: ===================================== compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs ===================================== @@ -554,8 +554,9 @@ delAssoc :: (Uniquable a) delAssoc a m | Just aSet <- lookupUFM m a , m1 <- delFromUFM m a - = nonDetFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet - -- It's OK to use nonDetFoldUFM here because deletion is commutative + = nonDetStrictFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet + -- It's OK to use a non-deterministic fold here because deletion is + -- commutative | otherwise = m ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -380,8 +380,8 @@ famInstEnvElts fi = [elt | FamIE elts <- eltsUDFM fi, elt <- elts] -- See Note [FamInstEnv determinism] famInstEnvSize :: FamInstEnv -> Int -famInstEnvSize = nonDetFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 - -- It's OK to use nonDetFoldUDFM here since we're just computing the +famInstEnvSize = nonDetStrictFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 + -- It's OK to use nonDetStrictFoldUDFM here since we're just computing the -- size. familyInstances :: (FamInstEnv, FamInstEnv) -> TyCon -> [FamInst] ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -2243,8 +2243,8 @@ extendFvs env s = (s `unionVarSet` extras, extras `subVarSet` s) where extras :: VarSet -- env(s) - extras = nonDetFoldUFM unionVarSet emptyVarSet $ - -- It's OK to use nonDetFoldUFM here because unionVarSet commutes + extras = nonDetStrictFoldUFM unionVarSet emptyVarSet $ + -- It's OK to use nonDetStrictFoldUFM here because unionVarSet commutes intersectUFM_C (\x _ -> x) env (getUniqSet s) {- @@ -2565,8 +2565,8 @@ addManyOcc v u | isId v = addManyOccId u v -- (Same goes for INLINE.) addManyOccs :: UsageDetails -> VarSet -> UsageDetails -addManyOccs usage id_set = nonDetFoldUniqSet addManyOcc usage id_set - -- It's OK to use nonDetFoldUFM here because addManyOcc commutes +addManyOccs usage id_set = nonDetStrictFoldUniqSet addManyOcc usage id_set + -- It's OK to use nonDetStrictFoldUniqSet here because addManyOcc commutes delDetails :: UsageDetails -> Id -> UsageDetails delDetails ud bndr ===================================== compiler/GHC/Core/Op/SetLevels.hs ===================================== @@ -83,7 +83,7 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Var import GHC.Types.Var.Set -import GHC.Types.Unique.Set ( nonDetFoldUniqSet ) +import GHC.Types.Unique.Set ( nonDetStrictFoldUniqSet ) import GHC.Types.Unique.DSet ( getUniqDSet ) import GHC.Types.Var.Env import GHC.Types.Literal ( litIsTrivial ) @@ -1469,8 +1469,8 @@ isFunction (_, AnnLam b e) | isId b = True isFunction _ = False countFreeIds :: DVarSet -> Int -countFreeIds = nonDetFoldUDFM add 0 . getUniqDSet - -- It's OK to use nonDetFoldUDFM here because we're just counting things. +countFreeIds = nonDetStrictFoldUDFM add 0 . getUniqDSet + -- It's OK to use nonDetStrictFoldUDFM here because we're just counting things. where add :: Var -> Int -> Int add v n | isId v = n+1 @@ -1581,12 +1581,14 @@ placeJoinCeiling le@(LE { le_ctxt_lvl = lvl }) maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level maxFvLevel max_me env var_set - = foldDVarSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet maxFvLevel' max_me env var_set - = nonDetFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -2177,8 +2177,8 @@ unionCallInfoSet (CIS f calls1) (CIS _ calls2) = callDetailsFVs :: CallDetails -> VarSet callDetailsFVs calls = - nonDetFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls - -- It's OK to use nonDetFoldUDFM here because we forget the ordering + nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls + -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering -- immediately by converting to a nondeterministic set. callInfoFVs :: CallInfoSet -> VarSet ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -441,7 +441,7 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView closeOverKinds :: TyCoVarSet -> TyCoVarSet -- For each element of the input set, -- add the deep free variables of its kind -closeOverKinds vs = nonDetFoldVarSet do_one vs vs +closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs where do_one v acc = appEndo (deep_ty (varType v)) acc ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -658,9 +658,9 @@ niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet -- remembering that the substitution isn't necessarily idempotent -- This is used in the occurs check, before extending the substitution niSubstTvSet tsubst tvs - = nonDetFoldUniqSet (unionVarSet . get) emptyVarSet tvs - -- It's OK to nonDetFoldUFM here because we immediately forget the - -- ordering by creating a set. + = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs + -- It's OK to use a non-deterministic fold here because we immediately forget + -- the ordering by creating a set. where get tv | Just ty <- lookupVarEnv tsubst tv ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -260,9 +260,9 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names -- ent_map groups together all the things imported and used -- from a particular module ent_map :: ModuleEnv [OccName] - ent_map = nonDetFoldUniqSet add_mv emptyModuleEnv used_names - -- nonDetFoldUFM is OK here. If you follow the logic, we sort by OccName - -- in ent_hashs + ent_map = nonDetStrictFoldUniqSet add_mv emptyModuleEnv used_names + -- nonDetStrictFoldUniqSet is OK here. If you follow the logic, we sort by + -- OccName in ent_hashs where add_mv name mv_map | isWiredInName name = mv_map -- ignore wired-in names ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -1422,8 +1422,8 @@ depAnalTyClDecls rdr_env kisig_fv_env ds_w_fvs toParents :: GlobalRdrEnv -> NameSet -> NameSet toParents rdr_env ns - = nonDetFoldUniqSet add emptyNameSet ns - -- It's OK to use nonDetFoldUFM because we immediately forget the + = nonDetStrictFoldUniqSet add emptyNameSet ns + -- It's OK to use a non-deterministic fold because we immediately forget the -- ordering by creating a set where add n s = extendNameSet s (getParent rdr_env n) ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -545,7 +545,8 @@ closureGrowth expander sizer group abs_ids = go -- we lift @f@ newbies = abs_ids `minusDVarSet` clo_fvs' -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ - cost = foldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + -- Using a non-deterministic fold is OK here because addition is commutative. go (RhsSk body_dmd body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -785,16 +785,23 @@ cleanUseDmd_maybe _ = Nothing splitFVs :: Bool -- Thunk -> DmdEnv -> (DmdEnv, DmdEnv) splitFVs is_thunk rhs_fvs - | is_thunk = nonDetFoldUFM_Directly add (emptyVarEnv, emptyVarEnv) rhs_fvs - -- It's OK to use nonDetFoldUFM_Directly because we + | is_thunk = strictPairToTuple $ + nonDetStrictFoldUFM_Directly add (emptyVarEnv :*: emptyVarEnv) rhs_fvs + -- It's OK to use a non-deterministic fold because we -- immediately forget the ordering by putting the elements -- in the envs again | otherwise = partitionVarEnv isWeakDmd rhs_fvs where - add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv, sig_fv) - | Lazy <- s = (addToUFM_Directly lazy_fv uniq dmd, sig_fv) - | otherwise = ( addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) - , addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) ) + add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv :*: sig_fv) + | Lazy <- s = addToUFM_Directly lazy_fv uniq dmd :*: sig_fv + | otherwise = addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) + :*: + addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) + +data StrictPair a b = !a :*: !b + +strictPairToTuple :: StrictPair a b -> (a, b) +strictPairToTuple (x :*: y) = (x, y) data TypeShape = TsFun TypeShape | TsProd [TypeShape] ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -50,14 +50,14 @@ module GHC.Types.Unique.DFM ( equalKeysUDFM, minusUDFM, listToUDFM, - udfmMinusUFM, + udfmMinusUFM, ufmMinusUDFM, partitionUDFM, anyUDFM, allUDFM, pprUniqDFM, pprUDFM, udfmToList, udfmToUfm, - nonDetFoldUDFM, + nonDetStrictFoldUDFM, alwaysUnsafeUfmToUdfm, ) where @@ -72,7 +72,7 @@ import Data.Functor.Classes (Eq1 (..)) import Data.List (sortBy) import Data.Function (on) import qualified Data.Semigroup as Semi -import GHC.Types.Unique.FM (UniqFM, listToUFM_Directly, nonDetUFMToList, ufmToIntMap) +import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM) -- Note [Deterministic UniqFM] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -272,12 +272,14 @@ elemUDFM k (UDFM m _i) = M.member (getKey $ getUnique k) m foldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a foldUDFM k z m = foldr k z (eltsUDFM m) --- | Performs a nondeterministic fold over the UniqDFM. +-- | Performs a nondeterministic strict fold over the UniqDFM. -- It's O(n), same as the corresponding function on `UniqFM`. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a -nonDetFoldUDFM k z (UDFM m _i) = foldr k z $ map taggedFst $ M.elems m +nonDetStrictFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a +nonDetStrictFoldUDFM k z (UDFM m _i) = foldl' k' z m + where + k' acc (TaggedVal v _) = k v acc eltsUDFM :: UniqDFM elt -> [elt] eltsUDFM (UDFM m _i) = @@ -337,6 +339,9 @@ udfmMinusUFM (UDFM x i) y = UDFM (M.difference x (ufmToIntMap y)) i -- M.difference returns a subset of a left set, so `i` is a good upper -- bound. +ufmMinusUDFM :: UniqFM elt1 -> UniqDFM elt2 -> UniqFM elt1 +ufmMinusUDFM x (UDFM y _i) = unsafeIntMapToUFM (M.difference (ufmToIntMap x) y) + -- | Partition UniqDFM into two UniqDFMs according to the predicate partitionUDFM :: (elt -> Bool) -> UniqDFM elt -> (UniqDFM elt, UniqDFM elt) partitionUDFM p (UDFM m i) = @@ -349,8 +354,7 @@ delListFromUDFM = foldl' delFromUDFM -- | This allows for lossy conversion from UniqDFM to UniqFM udfmToUfm :: UniqDFM elt -> UniqFM elt -udfmToUfm (UDFM m _i) = - listToUFM_Directly [(getUnique k, taggedFst tv) | (k, tv) <- M.toList m] +udfmToUfm (UDFM m _i) = unsafeIntMapToUFM (M.map taggedFst m) listToUDFM :: Uniquable key => [(key,elt)] -> UniqDFM elt listToUDFM = foldl' (\m (k, v) -> addToUDFM m k v) emptyUDFM ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, - foldUniqDSet, + nonDetStrictFoldUniqDSet, elementOfUniqDSet, filterUniqDSet, sizeUniqDSet, @@ -98,8 +98,11 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) -foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b -foldUniqDSet c n (UniqDSet s) = foldUDFM c n s +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b +nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s elementOfUniqDSet :: Uniquable a => a -> UniqDSet a -> Bool elementOfUniqDSet k = elemUDFM k . getUniqDSet ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Types.Unique.FM ( intersectUFM_C, disjointUFM, equalKeysUFM, - nonDetFoldUFM, foldUFM, nonDetFoldUFM_Directly, + nonDetStrictFoldUFM, foldUFM, nonDetStrictFoldUFM_Directly, anyUFM, allUFM, seqEltsUFM, mapUFM, mapUFM_Directly, elemUFM, elemUFM_Directly, @@ -67,7 +67,7 @@ module GHC.Types.Unique.FM ( lookupWithDefaultUFM, lookupWithDefaultUFM_Directly, nonDetEltsUFM, eltsUFM, nonDetKeysUFM, ufmToSet_Directly, - nonDetUFMToList, ufmToIntMap, + nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM, pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM ) where @@ -318,14 +318,14 @@ nonDetKeysUFM (UFM m) = map getUnique $ M.keys m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM k z (UFM m) = M.foldr k z m +nonDetStrictFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM_Directly k z (UFM m) = M.foldrWithKey (k . getUnique) z m +nonDetStrictFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (getUnique i) x z') z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce @@ -359,6 +359,9 @@ instance Traversable NonDetUniqFM where ufmToIntMap :: UniqFM elt -> M.IntMap elt ufmToIntMap (UFM m) = m +unsafeIntMapToUFM :: M.IntMap elt -> UniqFM elt +unsafeIntMapToUFM = UFM + -- Determines whether two 'UniqFM's contain the same keys. equalKeysUFM :: UniqFM a -> UniqFM b -> Bool equalKeysUFM (UFM m1) (UFM m2) = liftEq (\_ _ -> True) m1 m2 ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -25,7 +25,7 @@ module GHC.Types.Unique.Set ( delOneFromUniqSet, delOneFromUniqSet_Directly, delListFromUniqSet, delListFromUniqSet_Directly, unionUniqSets, unionManyUniqSets, - minusUniqSet, uniqSetMinusUFM, + minusUniqSet, uniqSetMinusUFM, uniqSetMinusUDFM, intersectUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, @@ -42,12 +42,12 @@ module GHC.Types.Unique.Set ( unsafeUFMToUniqSet, nonDetEltsUniqSet, nonDetKeysUniqSet, - nonDetFoldUniqSet, - nonDetFoldUniqSet_Directly + nonDetStrictFoldUniqSet, ) where import GhcPrelude +import GHC.Types.Unique.DFM import GHC.Types.Unique.FM import GHC.Types.Unique import Data.Coerce @@ -111,6 +111,9 @@ restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) uniqSetMinusUFM :: UniqSet a -> UniqFM b -> UniqSet a uniqSetMinusUFM (UniqSet s) t = UniqSet (minusUFM s t) +uniqSetMinusUDFM :: UniqSet a -> UniqDFM b -> UniqSet a +uniqSetMinusUDFM (UniqSet s) t = UniqSet (ufmMinusUDFM s t) + elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool elementOfUniqSet a (UniqSet s) = elemUFM a s @@ -159,14 +162,8 @@ nonDetKeysUniqSet = nonDetKeysUFM . getUniqSet' -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet c n (UniqSet s) = nonDetFoldUFM c n s - --- See Note [Deterministic UniqFM] to learn about nondeterminism. --- If you use this please provide a justification why it doesn't introduce --- nondeterminism. -nonDetFoldUniqSet_Directly:: (Unique -> elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet_Directly f n (UniqSet s) = nonDetFoldUFM_Directly f n s +nonDetStrictFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a +nonDetStrictFoldUniqSet c n (UniqSet s) = nonDetStrictFoldUFM c n s -- See Note [UniqSet invariant] mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Types.Var.Env ( extendDVarEnv, extendDVarEnv_C, extendDVarEnvList, lookupDVarEnv, elemDVarEnv, - isEmptyDVarEnv, foldDVarEnv, + isEmptyDVarEnv, foldDVarEnv, nonDetStrictFoldDVarEnv, mapDVarEnv, filterDVarEnv, modifyDVarEnv, alterDVarEnv, @@ -583,6 +583,12 @@ lookupDVarEnv = lookupUDFM foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b foldDVarEnv = foldUDFM +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b +nonDetStrictFoldDVarEnv = nonDetStrictFoldUDFM + mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b mapDVarEnv = mapUDFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Types.Var.Set ( sizeVarSet, seqVarSet, elemVarSetByKey, partitionVarSet, pluralVarSet, pprVarSet, - nonDetFoldVarSet, + nonDetStrictFoldVarSet, -- * Deterministic Var set types DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, @@ -36,7 +36,9 @@ module GHC.Types.Var.Set ( intersectDVarSet, dVarSetIntersectVarSet, intersectsDVarSet, disjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, - minusDVarSet, foldDVarSet, filterDVarSet, mapDVarSet, + minusDVarSet, + nonDetStrictFoldDVarSet, + filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, transCloDVarSet, sizeDVarSet, seqDVarSet, @@ -152,8 +154,11 @@ allVarSet = uniqSetAll mapVarSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapVarSet = mapUniqSet -nonDetFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a -nonDetFoldVarSet = nonDetFoldUniqSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a +nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet fixVarSet :: (VarSet -> VarSet) -- Map the current set to a new set -> VarSet -> VarSet @@ -290,8 +295,11 @@ minusDVarSet = minusUniqDSet dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet dVarSetMinusVarSet = uniqDSetMinusUniqSet -foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a -foldDVarSet = foldUniqDSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a +nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet anyDVarSet :: (Var -> Bool) -> DVarSet -> Bool anyDVarSet p = anyUDFM p . getUniqDSet ===================================== compiler/typecheck/TcEvidence.hs ===================================== @@ -15,8 +15,12 @@ module TcEvidence ( -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), EvBindMap(..), emptyEvBindMap, extendEvBinds, - lookupEvBind, evBindMapBinds, foldEvBindMap, filterEvBindMap, + lookupEvBind, evBindMapBinds, + foldEvBindMap, nonDetStrictFoldEvBindMap, + filterEvBindMap, isEmptyEvBindMap, + evBindMapToVarSet, + varSetMinusEvBindMap, EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, evBindVar, isCoEvBindsVar, @@ -55,6 +59,8 @@ module TcEvidence ( import GhcPrelude +import GHC.Types.Unique.DFM +import GHC.Types.Unique.FM import GHC.Types.Var import GHC.Core.Coercion.Axiom import GHC.Core.Coercion @@ -496,10 +502,22 @@ evBindMapBinds = foldEvBindMap consBag emptyBag foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a +nonDetStrictFoldEvBindMap k z bs = nonDetStrictFoldDVarEnv k z (ev_bind_varenv bs) + filterEvBindMap :: (EvBind -> Bool) -> EvBindMap -> EvBindMap filterEvBindMap k (EvBindMap { ev_bind_varenv = env }) = EvBindMap { ev_bind_varenv = filterDVarEnv k env } +evBindMapToVarSet :: EvBindMap -> VarSet +evBindMapToVarSet (EvBindMap dve) = unsafeUFMToUniqSet (mapUFM evBindVar (udfmToUfm dve)) + +varSetMinusEvBindMap :: VarSet -> EvBindMap -> VarSet +varSetMinusEvBindMap vs (EvBindMap dve) = vs `uniqSetMinusUDFM` dve + instance Outputable EvBindMap where ppr (EvBindMap m) = ppr m @@ -851,8 +869,8 @@ findNeededEvVars ev_binds seeds = transCloVarSet also_needs seeds where also_needs :: VarSet -> VarSet - also_needs needs = nonDetFoldUniqSet add emptyVarSet needs - -- It's OK to use nonDetFoldUFM here because we immediately + also_needs needs = nonDetStrictFoldUniqSet add emptyVarSet needs + -- It's OK to use a non-deterministic fold here because we immediately -- forget about the ordering by creating a set add :: Var -> VarSet -> VarSet ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -1862,11 +1862,13 @@ neededEvVars implic@(Implic { ic_given = givens ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var ; let seeds1 = foldr add_implic_seeds old_needs implics - seeds2 = foldEvBindMap add_wanted seeds1 ev_binds + seeds2 = nonDetStrictFoldEvBindMap add_wanted seeds1 ev_binds + -- It's OK to use a non-deterministic fold here + -- because add_wanted is commutative seeds3 = seeds2 `unionVarSet` tcvs need_inner = findNeededEvVars ev_binds seeds3 live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds - need_outer = foldEvBindMap del_ev_bndr need_inner live_ev_binds + need_outer = varSetMinusEvBindMap need_inner live_ev_binds `delVarSetList` givens ; TcS.setTcEvBindsMap ev_binds_var live_ev_binds @@ -1890,9 +1892,6 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = ev_var `elemVarSet` needed | otherwise = True -- Keep all wanted bindings - del_ev_bndr :: EvBind -> VarSet -> VarSet - del_ev_bndr (EvBind { eb_lhs = v }) needs = delVarSet needs v - add_wanted :: EvBind -> VarSet -> VarSet add_wanted (EvBind { eb_is_given = is_given, eb_rhs = rhs }) needs | is_given = needs -- Add the rhs vars of the Wanted bindings only @@ -2381,7 +2380,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs seed_skols = mkVarSet skols `unionVarSet` mkVarSet given_ids `unionVarSet` foldr add_non_flt_ct emptyVarSet no_float_cts `unionVarSet` - foldEvBindMap add_one_bind emptyVarSet binds + evBindMapToVarSet binds -- seed_skols: See Note [What prevents a constraint from floating] (1,2,3) -- Include the EvIds of any non-floating constraints @@ -2406,9 +2405,6 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs ; return ( flt_eqs, wanteds { wc_simple = remaining_simples } ) } where - add_one_bind :: EvBind -> VarSet -> VarSet - add_one_bind bind acc = extendVarSet acc (evBindVar bind) - add_non_flt_ct :: Ct -> VarSet -> VarSet add_non_flt_ct ct acc | isDerivedCt ct = acc | otherwise = extendVarSet acc (ctEvId ct) ===================================== compiler/typecheck/TcType.hs ===================================== @@ -703,7 +703,9 @@ tcTyVarLevel tv tcTypeLevel :: TcType -> TcLevel -- Max level of any free var of the type tcTypeLevel ty - = foldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + = nonDetStrictFoldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + -- It's safe to use a non-deterministic fold because `maxTcLevel` is + -- commutative. where add v lvl | isTcTyVar v = lvl `maxTcLevel` tcTyVarLevel v ===================================== compiler/utils/GraphOps.hs ===================================== @@ -63,8 +63,8 @@ addNode k node graph = let -- add back conflict edges from other nodes to this one map_conflict = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeConflicts = addOneToUniqSet (nodeConflicts n) k})) @@ -73,8 +73,8 @@ addNode k node graph -- add back coalesce edges from other nodes to this one map_coalesce = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeCoalesce = addOneToUniqSet (nodeCoalesce n) k})) @@ -476,9 +476,9 @@ freezeNode k else node -- panic "GraphOps.freezeNode: edge to freeze wasn't in the coalesce set" -- If the edge isn't actually in the coelesce set then just ignore it. - fm2 = nonDetFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 - -- It's OK to use nonDetFoldUFM here because the operation - -- is commutative + fm2 = nonDetStrictFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 + -- It's OK to use a non-deterministic fold here because the + -- operation is commutative $ nodeCoalesce node in fm2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/140fadd3352d89510cf6a20a13e3f8f11235591b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/140fadd3352d89510cf6a20a13e3f8f11235591b You're receiving 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 2 17:15:27 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 13:15:27 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] Improve some folds over Uniq[D]FM Message-ID: <5e861dafdb2d8_61673f81cca05dd82608520@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: 5006a7e1 by Simon Jakobi at 2020-04-02T19:15:05+02:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 21 changed files: - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs - compiler/typecheck/TcEvidence.hs - compiler/typecheck/TcSimplify.hs - compiler/typecheck/TcType.hs - compiler/utils/GraphOps.hs Changes: ===================================== compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs ===================================== @@ -554,8 +554,9 @@ delAssoc :: (Uniquable a) delAssoc a m | Just aSet <- lookupUFM m a , m1 <- delFromUFM m a - = nonDetFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet - -- It's OK to use nonDetFoldUFM here because deletion is commutative + = nonDetStrictFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet + -- It's OK to use a non-deterministic fold here because deletion is + -- commutative | otherwise = m ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -380,8 +380,8 @@ famInstEnvElts fi = [elt | FamIE elts <- eltsUDFM fi, elt <- elts] -- See Note [FamInstEnv determinism] famInstEnvSize :: FamInstEnv -> Int -famInstEnvSize = nonDetFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 - -- It's OK to use nonDetFoldUDFM here since we're just computing the +famInstEnvSize = nonDetStrictFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 + -- It's OK to use nonDetStrictFoldUDFM here since we're just computing the -- size. familyInstances :: (FamInstEnv, FamInstEnv) -> TyCon -> [FamInst] ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -2243,8 +2243,8 @@ extendFvs env s = (s `unionVarSet` extras, extras `subVarSet` s) where extras :: VarSet -- env(s) - extras = nonDetFoldUFM unionVarSet emptyVarSet $ - -- It's OK to use nonDetFoldUFM here because unionVarSet commutes + extras = nonDetStrictFoldUFM unionVarSet emptyVarSet $ + -- It's OK to use nonDetStrictFoldUFM here because unionVarSet commutes intersectUFM_C (\x _ -> x) env (getUniqSet s) {- @@ -2565,8 +2565,8 @@ addManyOcc v u | isId v = addManyOccId u v -- (Same goes for INLINE.) addManyOccs :: UsageDetails -> VarSet -> UsageDetails -addManyOccs usage id_set = nonDetFoldUniqSet addManyOcc usage id_set - -- It's OK to use nonDetFoldUFM here because addManyOcc commutes +addManyOccs usage id_set = nonDetStrictFoldUniqSet addManyOcc usage id_set + -- It's OK to use nonDetStrictFoldUniqSet here because addManyOcc commutes delDetails :: UsageDetails -> Id -> UsageDetails delDetails ud bndr ===================================== compiler/GHC/Core/Op/SetLevels.hs ===================================== @@ -83,7 +83,7 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Var import GHC.Types.Var.Set -import GHC.Types.Unique.Set ( nonDetFoldUniqSet ) +import GHC.Types.Unique.Set ( nonDetStrictFoldUniqSet ) import GHC.Types.Unique.DSet ( getUniqDSet ) import GHC.Types.Var.Env import GHC.Types.Literal ( litIsTrivial ) @@ -1469,8 +1469,8 @@ isFunction (_, AnnLam b e) | isId b = True isFunction _ = False countFreeIds :: DVarSet -> Int -countFreeIds = nonDetFoldUDFM add 0 . getUniqDSet - -- It's OK to use nonDetFoldUDFM here because we're just counting things. +countFreeIds = nonDetStrictFoldUDFM add 0 . getUniqDSet + -- It's OK to use nonDetStrictFoldUDFM here because we're just counting things. where add :: Var -> Int -> Int add v n | isId v = n+1 @@ -1581,12 +1581,14 @@ placeJoinCeiling le@(LE { le_ctxt_lvl = lvl }) maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level maxFvLevel max_me env var_set - = foldDVarSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet maxFvLevel' max_me env var_set - = nonDetFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -2177,8 +2177,8 @@ unionCallInfoSet (CIS f calls1) (CIS _ calls2) = callDetailsFVs :: CallDetails -> VarSet callDetailsFVs calls = - nonDetFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls - -- It's OK to use nonDetFoldUDFM here because we forget the ordering + nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls + -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering -- immediately by converting to a nondeterministic set. callInfoFVs :: CallInfoSet -> VarSet ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -441,7 +441,7 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView closeOverKinds :: TyCoVarSet -> TyCoVarSet -- For each element of the input set, -- add the deep free variables of its kind -closeOverKinds vs = nonDetFoldVarSet do_one vs vs +closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs where do_one v acc = appEndo (deep_ty (varType v)) acc ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -658,9 +658,9 @@ niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet -- remembering that the substitution isn't necessarily idempotent -- This is used in the occurs check, before extending the substitution niSubstTvSet tsubst tvs - = nonDetFoldUniqSet (unionVarSet . get) emptyVarSet tvs - -- It's OK to nonDetFoldUFM here because we immediately forget the - -- ordering by creating a set. + = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs + -- It's OK to use a non-deterministic fold here because we immediately forget + -- the ordering by creating a set. where get tv | Just ty <- lookupVarEnv tsubst tv ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -260,9 +260,9 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names -- ent_map groups together all the things imported and used -- from a particular module ent_map :: ModuleEnv [OccName] - ent_map = nonDetFoldUniqSet add_mv emptyModuleEnv used_names - -- nonDetFoldUFM is OK here. If you follow the logic, we sort by OccName - -- in ent_hashs + ent_map = nonDetStrictFoldUniqSet add_mv emptyModuleEnv used_names + -- nonDetStrictFoldUniqSet is OK here. If you follow the logic, we sort by + -- OccName in ent_hashs where add_mv name mv_map | isWiredInName name = mv_map -- ignore wired-in names ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -1422,8 +1422,8 @@ depAnalTyClDecls rdr_env kisig_fv_env ds_w_fvs toParents :: GlobalRdrEnv -> NameSet -> NameSet toParents rdr_env ns - = nonDetFoldUniqSet add emptyNameSet ns - -- It's OK to use nonDetFoldUFM because we immediately forget the + = nonDetStrictFoldUniqSet add emptyNameSet ns + -- It's OK to use a non-deterministic fold because we immediately forget the -- ordering by creating a set where add n s = extendNameSet s (getParent rdr_env n) ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -545,7 +545,8 @@ closureGrowth expander sizer group abs_ids = go -- we lift @f@ newbies = abs_ids `minusDVarSet` clo_fvs' -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ - cost = foldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + -- Using a non-deterministic fold is OK here because addition is commutative. go (RhsSk body_dmd body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -785,16 +785,23 @@ cleanUseDmd_maybe _ = Nothing splitFVs :: Bool -- Thunk -> DmdEnv -> (DmdEnv, DmdEnv) splitFVs is_thunk rhs_fvs - | is_thunk = nonDetFoldUFM_Directly add (emptyVarEnv, emptyVarEnv) rhs_fvs - -- It's OK to use nonDetFoldUFM_Directly because we + | is_thunk = strictPairToTuple $ + nonDetStrictFoldUFM_Directly add (emptyVarEnv :*: emptyVarEnv) rhs_fvs + -- It's OK to use a non-deterministic fold because we -- immediately forget the ordering by putting the elements -- in the envs again | otherwise = partitionVarEnv isWeakDmd rhs_fvs where - add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv, sig_fv) - | Lazy <- s = (addToUFM_Directly lazy_fv uniq dmd, sig_fv) - | otherwise = ( addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) - , addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) ) + add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv :*: sig_fv) + | Lazy <- s = addToUFM_Directly lazy_fv uniq dmd :*: sig_fv + | otherwise = addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) + :*: + addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) + +data StrictPair a b = !a :*: !b + +strictPairToTuple :: StrictPair a b -> (a, b) +strictPairToTuple (x :*: y) = (x, y) data TypeShape = TsFun TypeShape | TsProd [TypeShape] ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -50,14 +50,14 @@ module GHC.Types.Unique.DFM ( equalKeysUDFM, minusUDFM, listToUDFM, - udfmMinusUFM, + udfmMinusUFM, ufmMinusUDFM, partitionUDFM, anyUDFM, allUDFM, pprUniqDFM, pprUDFM, udfmToList, udfmToUfm, - nonDetFoldUDFM, + nonDetStrictFoldUDFM, alwaysUnsafeUfmToUdfm, ) where @@ -72,7 +72,7 @@ import Data.Functor.Classes (Eq1 (..)) import Data.List (sortBy) import Data.Function (on) import qualified Data.Semigroup as Semi -import GHC.Types.Unique.FM (UniqFM, listToUFM_Directly, nonDetUFMToList, ufmToIntMap) +import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM) -- Note [Deterministic UniqFM] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -272,12 +272,14 @@ elemUDFM k (UDFM m _i) = M.member (getKey $ getUnique k) m foldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a foldUDFM k z m = foldr k z (eltsUDFM m) --- | Performs a nondeterministic fold over the UniqDFM. +-- | Performs a nondeterministic strict fold over the UniqDFM. -- It's O(n), same as the corresponding function on `UniqFM`. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a -nonDetFoldUDFM k z (UDFM m _i) = foldr k z $ map taggedFst $ M.elems m +nonDetStrictFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a +nonDetStrictFoldUDFM k z (UDFM m _i) = foldl' k' z m + where + k' acc (TaggedVal v _) = k v acc eltsUDFM :: UniqDFM elt -> [elt] eltsUDFM (UDFM m _i) = @@ -337,6 +339,9 @@ udfmMinusUFM (UDFM x i) y = UDFM (M.difference x (ufmToIntMap y)) i -- M.difference returns a subset of a left set, so `i` is a good upper -- bound. +ufmMinusUDFM :: UniqFM elt1 -> UniqDFM elt2 -> UniqFM elt1 +ufmMinusUDFM x (UDFM y _i) = unsafeIntMapToUFM (M.difference (ufmToIntMap x) y) + -- | Partition UniqDFM into two UniqDFMs according to the predicate partitionUDFM :: (elt -> Bool) -> UniqDFM elt -> (UniqDFM elt, UniqDFM elt) partitionUDFM p (UDFM m i) = @@ -349,8 +354,7 @@ delListFromUDFM = foldl' delFromUDFM -- | This allows for lossy conversion from UniqDFM to UniqFM udfmToUfm :: UniqDFM elt -> UniqFM elt -udfmToUfm (UDFM m _i) = - listToUFM_Directly [(getUnique k, taggedFst tv) | (k, tv) <- M.toList m] +udfmToUfm (UDFM m _i) = unsafeIntMapToUFM (M.map taggedFst m) listToUDFM :: Uniquable key => [(key,elt)] -> UniqDFM elt listToUDFM = foldl' (\m (k, v) -> addToUDFM m k v) emptyUDFM ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, - foldUniqDSet, + nonDetStrictFoldUniqDSet, elementOfUniqDSet, filterUniqDSet, sizeUniqDSet, @@ -98,8 +98,11 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) -foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b -foldUniqDSet c n (UniqDSet s) = foldUDFM c n s +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b +nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s elementOfUniqDSet :: Uniquable a => a -> UniqDSet a -> Bool elementOfUniqDSet k = elemUDFM k . getUniqDSet ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Types.Unique.FM ( intersectUFM_C, disjointUFM, equalKeysUFM, - nonDetFoldUFM, foldUFM, nonDetFoldUFM_Directly, + nonDetStrictFoldUFM, foldUFM, nonDetStrictFoldUFM_Directly, anyUFM, allUFM, seqEltsUFM, mapUFM, mapUFM_Directly, elemUFM, elemUFM_Directly, @@ -67,7 +67,7 @@ module GHC.Types.Unique.FM ( lookupWithDefaultUFM, lookupWithDefaultUFM_Directly, nonDetEltsUFM, eltsUFM, nonDetKeysUFM, ufmToSet_Directly, - nonDetUFMToList, ufmToIntMap, + nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM, pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM ) where @@ -318,14 +318,14 @@ nonDetKeysUFM (UFM m) = map getUnique $ M.keys m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM k z (UFM m) = M.foldr k z m +nonDetStrictFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM_Directly k z (UFM m) = M.foldrWithKey (k . getUnique) z m +nonDetStrictFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (getUnique i) x z') z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce @@ -359,6 +359,9 @@ instance Traversable NonDetUniqFM where ufmToIntMap :: UniqFM elt -> M.IntMap elt ufmToIntMap (UFM m) = m +unsafeIntMapToUFM :: M.IntMap elt -> UniqFM elt +unsafeIntMapToUFM = UFM + -- Determines whether two 'UniqFM's contain the same keys. equalKeysUFM :: UniqFM a -> UniqFM b -> Bool equalKeysUFM (UFM m1) (UFM m2) = liftEq (\_ _ -> True) m1 m2 ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -25,7 +25,7 @@ module GHC.Types.Unique.Set ( delOneFromUniqSet, delOneFromUniqSet_Directly, delListFromUniqSet, delListFromUniqSet_Directly, unionUniqSets, unionManyUniqSets, - minusUniqSet, uniqSetMinusUFM, + minusUniqSet, uniqSetMinusUFM, uniqSetMinusUDFM, intersectUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, @@ -42,12 +42,12 @@ module GHC.Types.Unique.Set ( unsafeUFMToUniqSet, nonDetEltsUniqSet, nonDetKeysUniqSet, - nonDetFoldUniqSet, - nonDetFoldUniqSet_Directly + nonDetStrictFoldUniqSet, ) where import GhcPrelude +import GHC.Types.Unique.DFM import GHC.Types.Unique.FM import GHC.Types.Unique import Data.Coerce @@ -111,6 +111,9 @@ restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) uniqSetMinusUFM :: UniqSet a -> UniqFM b -> UniqSet a uniqSetMinusUFM (UniqSet s) t = UniqSet (minusUFM s t) +uniqSetMinusUDFM :: UniqSet a -> UniqDFM b -> UniqSet a +uniqSetMinusUDFM (UniqSet s) t = UniqSet (ufmMinusUDFM s t) + elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool elementOfUniqSet a (UniqSet s) = elemUFM a s @@ -159,14 +162,8 @@ nonDetKeysUniqSet = nonDetKeysUFM . getUniqSet' -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet c n (UniqSet s) = nonDetFoldUFM c n s - --- See Note [Deterministic UniqFM] to learn about nondeterminism. --- If you use this please provide a justification why it doesn't introduce --- nondeterminism. -nonDetFoldUniqSet_Directly:: (Unique -> elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet_Directly f n (UniqSet s) = nonDetFoldUFM_Directly f n s +nonDetStrictFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a +nonDetStrictFoldUniqSet c n (UniqSet s) = nonDetStrictFoldUFM c n s -- See Note [UniqSet invariant] mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Types.Var.Env ( extendDVarEnv, extendDVarEnv_C, extendDVarEnvList, lookupDVarEnv, elemDVarEnv, - isEmptyDVarEnv, foldDVarEnv, + isEmptyDVarEnv, foldDVarEnv, nonDetStrictFoldDVarEnv, mapDVarEnv, filterDVarEnv, modifyDVarEnv, alterDVarEnv, @@ -583,6 +583,12 @@ lookupDVarEnv = lookupUDFM foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b foldDVarEnv = foldUDFM +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b +nonDetStrictFoldDVarEnv = nonDetStrictFoldUDFM + mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b mapDVarEnv = mapUDFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Types.Var.Set ( sizeVarSet, seqVarSet, elemVarSetByKey, partitionVarSet, pluralVarSet, pprVarSet, - nonDetFoldVarSet, + nonDetStrictFoldVarSet, -- * Deterministic Var set types DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, @@ -36,7 +36,9 @@ module GHC.Types.Var.Set ( intersectDVarSet, dVarSetIntersectVarSet, intersectsDVarSet, disjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, - minusDVarSet, foldDVarSet, filterDVarSet, mapDVarSet, + minusDVarSet, + nonDetStrictFoldDVarSet, + filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, transCloDVarSet, sizeDVarSet, seqDVarSet, @@ -152,8 +154,11 @@ allVarSet = uniqSetAll mapVarSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapVarSet = mapUniqSet -nonDetFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a -nonDetFoldVarSet = nonDetFoldUniqSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a +nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet fixVarSet :: (VarSet -> VarSet) -- Map the current set to a new set -> VarSet -> VarSet @@ -290,8 +295,11 @@ minusDVarSet = minusUniqDSet dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet dVarSetMinusVarSet = uniqDSetMinusUniqSet -foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a -foldDVarSet = foldUniqDSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a +nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet anyDVarSet :: (Var -> Bool) -> DVarSet -> Bool anyDVarSet p = anyUDFM p . getUniqDSet ===================================== compiler/typecheck/TcEvidence.hs ===================================== @@ -15,8 +15,12 @@ module TcEvidence ( -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), EvBindMap(..), emptyEvBindMap, extendEvBinds, - lookupEvBind, evBindMapBinds, foldEvBindMap, filterEvBindMap, + lookupEvBind, evBindMapBinds, + foldEvBindMap, nonDetStrictFoldEvBindMap, + filterEvBindMap, isEmptyEvBindMap, + evBindMapToVarSet, + varSetMinusEvBindMap, EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, evBindVar, isCoEvBindsVar, @@ -55,6 +59,8 @@ module TcEvidence ( import GhcPrelude +import GHC.Types.Unique.DFM +import GHC.Types.Unique.FM import GHC.Types.Var import GHC.Core.Coercion.Axiom import GHC.Core.Coercion @@ -496,10 +502,22 @@ evBindMapBinds = foldEvBindMap consBag emptyBag foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a +nonDetStrictFoldEvBindMap k z bs = nonDetStrictFoldDVarEnv k z (ev_bind_varenv bs) + filterEvBindMap :: (EvBind -> Bool) -> EvBindMap -> EvBindMap filterEvBindMap k (EvBindMap { ev_bind_varenv = env }) = EvBindMap { ev_bind_varenv = filterDVarEnv k env } +evBindMapToVarSet :: EvBindMap -> VarSet +evBindMapToVarSet (EvBindMap dve) = unsafeUFMToUniqSet (mapUFM evBindVar (udfmToUfm dve)) + +varSetMinusEvBindMap :: VarSet -> EvBindMap -> VarSet +varSetMinusEvBindMap vs (EvBindMap dve) = vs `uniqSetMinusUDFM` dve + instance Outputable EvBindMap where ppr (EvBindMap m) = ppr m @@ -851,8 +869,8 @@ findNeededEvVars ev_binds seeds = transCloVarSet also_needs seeds where also_needs :: VarSet -> VarSet - also_needs needs = nonDetFoldUniqSet add emptyVarSet needs - -- It's OK to use nonDetFoldUFM here because we immediately + also_needs needs = nonDetStrictFoldUniqSet add emptyVarSet needs + -- It's OK to use a non-deterministic fold here because we immediately -- forget about the ordering by creating a set add :: Var -> VarSet -> VarSet ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -1862,11 +1862,13 @@ neededEvVars implic@(Implic { ic_given = givens ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var ; let seeds1 = foldr add_implic_seeds old_needs implics - seeds2 = foldEvBindMap add_wanted seeds1 ev_binds + seeds2 = nonDetStrictFoldEvBindMap add_wanted seeds1 ev_binds + -- It's OK to use a non-deterministic fold here + -- because add_wanted is commutative seeds3 = seeds2 `unionVarSet` tcvs need_inner = findNeededEvVars ev_binds seeds3 live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds - need_outer = foldEvBindMap del_ev_bndr need_inner live_ev_binds + need_outer = varSetMinusEvBindMap need_inner live_ev_binds `delVarSetList` givens ; TcS.setTcEvBindsMap ev_binds_var live_ev_binds @@ -1890,9 +1892,6 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = ev_var `elemVarSet` needed | otherwise = True -- Keep all wanted bindings - del_ev_bndr :: EvBind -> VarSet -> VarSet - del_ev_bndr (EvBind { eb_lhs = v }) needs = delVarSet needs v - add_wanted :: EvBind -> VarSet -> VarSet add_wanted (EvBind { eb_is_given = is_given, eb_rhs = rhs }) needs | is_given = needs -- Add the rhs vars of the Wanted bindings only @@ -2381,7 +2380,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs seed_skols = mkVarSet skols `unionVarSet` mkVarSet given_ids `unionVarSet` foldr add_non_flt_ct emptyVarSet no_float_cts `unionVarSet` - foldEvBindMap add_one_bind emptyVarSet binds + evBindMapToVarSet binds -- seed_skols: See Note [What prevents a constraint from floating] (1,2,3) -- Include the EvIds of any non-floating constraints @@ -2406,9 +2405,6 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs ; return ( flt_eqs, wanteds { wc_simple = remaining_simples } ) } where - add_one_bind :: EvBind -> VarSet -> VarSet - add_one_bind bind acc = extendVarSet acc (evBindVar bind) - add_non_flt_ct :: Ct -> VarSet -> VarSet add_non_flt_ct ct acc | isDerivedCt ct = acc | otherwise = extendVarSet acc (ctEvId ct) ===================================== compiler/typecheck/TcType.hs ===================================== @@ -703,7 +703,9 @@ tcTyVarLevel tv tcTypeLevel :: TcType -> TcLevel -- Max level of any free var of the type tcTypeLevel ty - = foldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + = nonDetStrictFoldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + -- It's safe to use a non-deterministic fold because `maxTcLevel` is + -- commutative. where add v lvl | isTcTyVar v = lvl `maxTcLevel` tcTyVarLevel v ===================================== compiler/utils/GraphOps.hs ===================================== @@ -63,8 +63,8 @@ addNode k node graph = let -- add back conflict edges from other nodes to this one map_conflict = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeConflicts = addOneToUniqSet (nodeConflicts n) k})) @@ -73,8 +73,8 @@ addNode k node graph -- add back coalesce edges from other nodes to this one map_coalesce = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeCoalesce = addOneToUniqSet (nodeCoalesce n) k})) @@ -476,9 +476,9 @@ freezeNode k else node -- panic "GraphOps.freezeNode: edge to freeze wasn't in the coalesce set" -- If the edge isn't actually in the coelesce set then just ignore it. - fm2 = nonDetFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 - -- It's OK to use nonDetFoldUFM here because the operation - -- is commutative + fm2 = nonDetStrictFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 + -- It's OK to use a non-deterministic fold here because the + -- operation is commutative $ nodeCoalesce node in fm2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5006a7e1088511af71ef009debcbf97bb7e801a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5006a7e1088511af71ef009debcbf97bb7e801a4 You're receiving 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 2 20:34:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 02 Apr 2020 16:34:17 -0400 Subject: [Git][ghc/ghc][wip/T15304] 79 commits: base: add strict IO functions: readFile', getContents', hGetContents' Message-ID: <5e864c498c7d1_616766534602628148@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 1001a085 by Ben Gamari at 2020-04-02T16:12:19-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Metric Decrease: T12234 T13035 T13719 T14683 T4801 T5631 T9020 T9961 Metric Increase: T14697 T15426 T1969 T5837 T9203 T9872a T9872b T9872c T9872d - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/linters/check-cpp.py - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e747493c48b93ad968ae011ceb82b481bbdc906...1001a085d08de5c3b7dbe338946228bb0cd446c7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e747493c48b93ad968ae011ceb82b481bbdc906...1001a085d08de5c3b7dbe338946228bb0cd446c7 You're receiving 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 2 20:57:09 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Thu, 02 Apr 2020 16:57:09 -0400 Subject: [Git][ghc/ghc][wip/T16806] 11 commits: PmCheck: Adjust recursion depth for inhabitation test Message-ID: <5e8651a5e168b_616713279f6c263193@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - a7e0945c by Simon Jakobi at 2020-04-02T22:56:31+02:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Module.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Set.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9191ffd6d705efb9ed7300149f972d026b6d89ef...a7e0945c10941c7e3440bb5e4aedd63142e2aff0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9191ffd6d705efb9ed7300149f972d026b6d89ef...a7e0945c10941c7e3440bb5e4aedd63142e2aff0 You're receiving 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 2 22:10:04 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Thu, 02 Apr 2020 18:10:04 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] WIP on in-tree annotations Message-ID: <5e8662bcc9369_6167136dfb9c26392d@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: e8277c02 by Alan Zimmerman at 2020-04-02T22:54:04+01:00 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/ThToHs.hs - compiler/main/HeaderInfo.hs - compiler/main/HscStats.hs - compiler/parser/Lexer.x - compiler/parser/Parser.y - compiler/parser/RdrHsSyn.hs - compiler/typecheck/TcBackpack.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcRnDriver.hs - compiler/typecheck/TcRnExports.hs - compiler/typecheck/TcRnMonad.hs - compiler/typecheck/TcRnTypes.hs - compiler/typecheck/TcRules.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/utils/OrdList.hs Changes: ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -695,6 +695,7 @@ summariseRequirement pn mod_name = do ms_textual_imps = extra_sig_imports, ms_parsed_mod = Just (HsParsedModule { hpm_module = L loc (HsModule { + hsmodAnn = noAnn, hsmodName = Just (L loc mod_name), hsmodExports = Nothing, hsmodImports = [], ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -394,7 +394,8 @@ hscParse' mod_summary srcs2 <- liftIO $ filterM doesFileExist srcs1 let api_anns = ApiAnns { - apiAnnItems = M.fromListWith (++) $ annotations pst, + -- AZ apiAnnItems = M.fromListWith (++) $ annotations pst, + apiAnnItems = M.empty, apiAnnEofPos = eof_pos pst, apiAnnComments = M.fromList (annotations_comments pst), apiAnnRogueComments = comment_q pst @@ -991,9 +992,9 @@ hscCheckSafeImports tcg_env = do warns dflags rules = listToBag $ map (warnRules dflags) rules - warnRules :: DynFlags -> GenLocated SrcSpan (RuleDecl GhcTc) -> ErrMsg + warnRules :: DynFlags -> LRuleDecl GhcTc -> ErrMsg warnRules dflags (L loc (HsRule { rd_name = n })) = - mkPlainWarnMsg dflags loc $ + mkPlainWarnMsg dflags (locA loc) $ text "Rule \"" <> ftext (snd $ unLoc n) <> text "\" ignored" $+$ text "User defined rules are disabled under Safe Haskell" warnRules _ (L _ (XRuleDecl nec)) = noExtCon nec ===================================== compiler/GHC/Hs.hs ===================================== @@ -63,10 +63,11 @@ import Data.Data hiding ( Fixity ) -- All we actually declare here is the top-level structure for a module. data HsModule = HsModule { + hsmodAnn :: ApiAnn, hsmodName :: Maybe (Located ModuleName), -- ^ @Nothing@: \"module X where\" is omitted (in which case the next -- field is Nothing too) - hsmodExports :: Maybe (Located [LIE GhcPs]), + hsmodExports :: Maybe (LocatedA [LIE GhcPs]), -- ^ Export list -- -- - @Nothing@: export list omitted, so export everything @@ -86,7 +87,7 @@ data HsModule -- downstream. hsmodDecls :: [LHsDecl GhcPs], -- ^ Type, class, value, and interface signature decls - hsmodDeprecMessage :: Maybe (Located WarningTxt), + hsmodDeprecMessage :: Maybe (LocatedA WarningTxt), -- ^ reason\/explanation for warning/deprecation of this module -- -- - 'ApiAnnotation.AnnKeywordId's : 'ApiAnnotation.AnnOpen' @@ -116,11 +117,11 @@ deriving instance Data HsModule instance Outputable HsModule where - ppr (HsModule Nothing _ imports decls _ mbDoc) + ppr (HsModule _ Nothing _ imports decls _ mbDoc) = pp_mb mbDoc $$ pp_nonnull imports $$ pp_nonnull decls - ppr (HsModule (Just name) exports imports decls deprec mbDoc) + ppr (HsModule _ (Just name) exports imports decls deprec mbDoc) = vcat [ pp_mb mbDoc, case exports of ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -1135,11 +1135,17 @@ type LInjectivityAnn pass = Located (InjectivityAnn pass) -- -- This will be represented as "InjectivityAnn `r` [`a`, `c`]" data InjectivityAnn pass - = InjectivityAnn (LocatedA (IdP pass)) [LocatedA (IdP pass)] + = InjectivityAnn (XCInjectivityAnn pass) + (LocatedA (IdP pass)) [LocatedA (IdP pass)] -- ^ - 'ApiAnnotation.AnnKeywordId' : -- 'ApiAnnotation.AnnRarrow', 'ApiAnnotation.AnnVbar' -- For details on above see note [Api annotations] in ApiAnnotation + | XInjectivityAnn !(XXInjectivityAnn pass) + +type instance XCInjectivityAnn (GhcPass _) = ApiAnn +type instance XXInjectivityAnn (GhcPass _) = NoExtCon + data FamilyInfo pass = DataFamily @@ -1201,8 +1207,9 @@ pprFamilyDecl top_level (FamilyDecl { fdInfo = info, fdLName = ltycon TyVarSig _ tv_bndr -> text "=" <+> ppr tv_bndr XFamilyResultSig nec -> noExtCon nec pp_inj = case mb_inj of - Just (L _ (InjectivityAnn lhs rhs)) -> + Just (L _ (InjectivityAnn _ lhs rhs)) -> hsep [ vbar, ppr lhs, text "->", hsep (map ppr rhs) ] + Just (L _ (XInjectivityAnn nec)) -> noExtCon nec Nothing -> empty (pp_where, pp_eqns) = case info of ClosedTypeFamily mb_eqns -> @@ -1241,7 +1248,7 @@ data HsDataDefn pass -- The payload of a data type defn HsDataDefn { dd_ext :: XCHsDataDefn pass, dd_ND :: NewOrData, dd_ctxt :: LHsContext pass, -- ^ Context - dd_cType :: Maybe (Located CType), + dd_cType :: Maybe (LocatedA CType), dd_kindSig:: Maybe (LHsKind pass), -- ^ Optional kind signature. -- @@ -1293,7 +1300,7 @@ data HsDerivingClause pass , deriv_clause_strategy :: Maybe (LDerivStrategy pass) -- ^ The user-specified strategy (if any) to use when deriving -- 'deriv_clause_tys'. - , deriv_clause_tys :: Located [LHsSigType pass] + , deriv_clause_tys :: LocatedA [LHsSigType pass] -- ^ The types to derive. -- -- It uses 'LHsSigType's because, with @-XGeneralizedNewtypeDeriving@, @@ -1628,7 +1635,7 @@ free-standing `type instance` declaration. ----------------- Type synonym family instances ------------- -- | Located Type Family Instance Equation -type LTyFamInstEqn pass = Located (TyFamInstEqn pass) +type LTyFamInstEqn pass = LocatedA (TyFamInstEqn pass) -- ^ May have 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi' -- when in a list @@ -1741,7 +1748,7 @@ data FamEqn pass rhs -- For details on above see note [Api annotations] in ApiAnnotation -type instance XCFamEqn (GhcPass _) r = NoExtField +type instance XCFamEqn (GhcPass _) r = ApiAnn type instance XXFamEqn (GhcPass _) r = NoExtCon ----------------- Class instances ------------- @@ -1760,7 +1767,7 @@ data ClsInstDecl pass , cid_sigs :: [LSig pass] -- User-supplied pragmatic info , cid_tyfam_insts :: [LTyFamInstDecl pass] -- Type family instances , cid_datafam_insts :: [LDataFamInstDecl pass] -- Data family instances - , cid_overlap_mode :: Maybe (Located OverlapMode) + , cid_overlap_mode :: Maybe (LocatedA OverlapMode) -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen', -- 'ApiAnnotation.AnnClose', @@ -1922,7 +1929,7 @@ ppDerivStrategy mb = Nothing -> empty Just (L _ ds) -> ppr ds -ppOverlapPragma :: Maybe (Located OverlapMode) -> SDoc +ppOverlapPragma :: Maybe (LocatedA OverlapMode) -> SDoc ppOverlapPragma mb = case mb of Nothing -> empty @@ -1982,7 +1989,7 @@ data DerivDecl pass = DerivDecl -- See Note [Inferring the instance context] in TcDerivInfer. , deriv_strategy :: Maybe (LDerivStrategy pass) - , deriv_overlap_mode :: Maybe (Located OverlapMode) + , deriv_overlap_mode :: Maybe (LocatedA OverlapMode) -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDeriving', -- 'ApiAnnotation.AnnInstance', 'ApiAnnotation.AnnStock', -- 'ApiAnnotation.AnnAnyClass', 'Api.AnnNewtype', @@ -1992,7 +1999,7 @@ data DerivDecl pass = DerivDecl } | XDerivDecl (XXDerivDecl pass) -type instance XCDerivDecl (GhcPass _) = NoExtField +type instance XCDerivDecl (GhcPass _) = ApiAnn type instance XXDerivDecl (GhcPass _) = NoExtCon instance OutputableBndrId p @@ -2170,11 +2177,11 @@ data ForeignDecl pass such as Int and IO that we know how to make foreign calls with. -} -type instance XForeignImport GhcPs = NoExtField +type instance XForeignImport GhcPs = ApiAnn type instance XForeignImport GhcRn = NoExtField type instance XForeignImport GhcTc = Coercion -type instance XForeignExport GhcPs = NoExtField +type instance XForeignExport GhcPs = ApiAnn type instance XForeignExport GhcRn = NoExtField type instance XForeignExport GhcTc = Coercion @@ -2292,7 +2299,7 @@ type instance XCRuleDecls GhcTc = NoExtField type instance XXRuleDecls (GhcPass _) = NoExtCon -- | Located Rule Declaration -type LRuleDecl pass = Located (RuleDecl pass) +type LRuleDecl pass = LocatedA (RuleDecl pass) -- | Rule Declaration data RuleDecl pass @@ -2322,7 +2329,7 @@ data RuleDecl pass data HsRuleRn = HsRuleRn NameSet NameSet -- Free-vars from the LHS and RHS deriving Data -type instance XHsRule GhcPs = NoExtField +type instance XHsRule GhcPs = ApiAnn type instance XHsRule GhcRn = HsRuleRn type instance XHsRule GhcTc = HsRuleRn ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -28,10 +28,11 @@ module GHC.Hs.Extension where import GhcPrelude import Data.Data hiding ( Fixity ) +import Data.Semigroup import Name import RdrName import Var -import Outputable +import Outputable hiding ((<>)) import SrcLoc (Located, GenLocated(..), RealLocated, SrcSpan, noSrcSpan) import Lexer (AddApiAnn) import ApiAnnotation @@ -261,6 +262,20 @@ data SrcSpanAnn = SrcSpanAnn { ann :: ApiAnn, locA :: SrcSpan } instance Outputable SrcSpanAnn where ppr (SrcSpanAnn a l) = text "SrcSpanAnn" <+> ppr a <+> ppr l +-- --------------------------------------------------------------------- +-- Managing annotations for lists +-- --------------------------------------------------------------------- + +data AnnList + = AnnList { + alOpenLoc :: SrcSpan, + alOpenKeyword :: AnnKeywordId, + alCloseLoc :: SrcSpan, + alCloseKeyword :: AnnKeywordId + } deriving (Data) + +-- --------------------------------------------------------------------- + reAnn :: [AddApiAnn] -> ApiAnnComments -> Located a -> LocatedA a reAnn anns cs (L l a) = L (SrcSpanAnn (ApiAnn anns cs) l) a @@ -293,6 +308,16 @@ addAnns (ApiAnn as1 cs) as2 cs2 = ApiAnn (as1 ++ as2) (cs ++ cs2) addAnns ApiAnnNotUsed [] [] = ApiAnnNotUsed addAnns ApiAnnNotUsed as cs = ApiAnn as cs + +instance (Semigroup a) => Semigroup (ApiAnn' a) where + ApiAnnNotUsed <> x = x + x <> ApiAnnNotUsed = x + (ApiAnn a1 b1) <> (ApiAnn a2 b2) = ApiAnn (a1 <> a2) (b1 <> b2) + +instance (Monoid a) => Monoid (ApiAnn' a) where + mempty = ApiAnnNotUsed + + instance (Outputable a) => Outputable (ApiAnn' a) where ppr (ApiAnn a c) = text "ApiAnn" <+> ppr a <+> ppr c ppr ApiAnnNotUsed = text "ApiAnnNotUsed" @@ -559,6 +584,11 @@ type family XXAnnDecl x type family XCRoleAnnotDecl x type family XXRoleAnnotDecl x +-- ------------------------------------- +-- InjectivityAnn type families +type family XCInjectivityAnn x +type family XXInjectivityAnn x + -- ===================================================================== -- Type families for the HsExpr extension points @@ -826,9 +856,6 @@ type family XIEDoc x type family XIEDocNamed x type family XXIE x --- ------------------------------------- - - -- ===================================================================== -- End of Type family definitions -- ===================================================================== ===================================== compiler/GHC/Hs/ImpExp.hs ===================================== @@ -43,7 +43,7 @@ One per \tr{import} declaration in a module. -} -- | Located Import Declaration -type LImportDecl pass = Located (ImportDecl pass) +type LImportDecl pass = LocatedA (ImportDecl pass) -- ^ When in a list this may have -- -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnSemi' @@ -88,7 +88,7 @@ data ImportDecl pass ideclQualified :: ImportDeclQualifiedStyle, -- ^ If/how the import is qualified. ideclImplicit :: Bool, -- ^ True => implicit import (of Prelude) ideclAs :: Maybe (Located ModuleName), -- ^ as Module - ideclHiding :: Maybe (Bool, Located [LIE pass]) + ideclHiding :: Maybe (Bool, LocatedA [LIE pass]) -- ^ (True => hiding, names) } | XImportDecl (XXImportDecl pass) @@ -197,7 +197,7 @@ type LIEWrappedName name = Located (IEWrappedName name) -- | Located Import or Export -type LIE pass = Located (IE pass) +type LIE pass = LocatedA (IE pass) -- ^ When in a list this may have -- -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnComma' ===================================== compiler/GHC/Hs/Types.hs ===================================== @@ -282,7 +282,7 @@ quantified in left-to-right order in kind signatures is nice since: -} -- | Located Haskell Context -type LHsContext pass = Located (HsContext pass) +type LHsContext pass = LocatedA (HsContext pass) -- ^ 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnUnit' -- For details on above see note [Api annotations] in ApiAnnotation @@ -292,7 +292,7 @@ noLHsContext :: LHsContext pass -- class () => C a where ... -- from -- class C a where ... -noLHsContext = noLoc [] +noLHsContext = noLocA [] -- | Haskell Context type HsContext pass = [LHsType pass] ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -673,7 +673,7 @@ typeToLHsType ty = case af of VisArg -> nlHsFunTy (go arg) (go res) InvisArg | (theta, tau) <- tcSplitPhiTy ty - -> noLoc (HsQualTy { hst_ctxt = noLoc (map go theta) + -> noLoc (HsQualTy { hst_ctxt = noLocA (map go theta) , hst_xqual = noAnn , hst_body = go tau }) ===================================== compiler/GHC/HsToCore.hs ===================================== @@ -379,7 +379,7 @@ dsRule (L loc (HsRule { rd_name = name , rd_tmvs = vars , rd_lhs = lhs , rd_rhs = rhs })) - = putSrcSpanDs loc $ + = putSrcSpanDs (locA loc) $ do { let bndrs' = [var | L _ (RuleBndr _ (L _ var)) <- vars] ; lhs' <- unsetGOptM Opt_EnableRewriteRules $ ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -598,7 +598,7 @@ repInjectivityAnn :: Maybe (LInjectivityAnn GhcRn) -> MetaM (Core (Maybe TH.InjectivityAnn)) repInjectivityAnn Nothing = do { coreNothing injAnnTyConName } -repInjectivityAnn (Just (L _ (InjectivityAnn lhs rhs))) = +repInjectivityAnn (Just (L _ (InjectivityAnn _ lhs rhs))) = do { lhs' <- lookupBinder (unLoc lhs) ; rhs1 <- mapM (lookupBinder . unLoc) rhs ; rhs2 <- coreList nameTyConName rhs1 @@ -840,7 +840,7 @@ repRuleD (L loc (HsRule { rd_name = n ; rhs' <- repLE rhs ; repPragRule n' ty_bndrs' tm_bndrs' lhs' rhs' act' } ; wrapGenSyms ss rule } - ; return (loc, rule) } + ; return (locA loc, rule) } repRuleD (L _ (XRuleDecl nec)) = noExtCon nec ruleBndrNames :: LRuleBndr GhcRn -> [Name] ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1297,7 +1297,7 @@ instance ToHie (LTyClDecl GhcRn) where , toHie defn ] where - quant_scope = mkLScope $ dd_ctxt defn + quant_scope = mkLScopeA $ dd_ctxt defn rhs_scope = sig_sc `combineScopes` con_sc `combineScopes` deriv_sc sig_sc = maybe NoScope mkLScope $ dd_kindSig defn con_sc = foldr combineScopes NoScope $ map mkLScope $ dd_cons defn @@ -1322,7 +1322,7 @@ instance ToHie (LTyClDecl GhcRn) where , toHie deftyps ] where - context_scope = mkLScope context + context_scope = mkLScopeA context rhs_scope = foldl1' combineScopes $ map mkScope [ loc deps, loc sigs, loc (bagToList meths), loc typs, loc deftyps] XTyClDecl _ -> [] @@ -1344,11 +1344,11 @@ instance ToHie (LFamilyDecl GhcRn) where instance ToHie (FamilyInfo GhcRn) where toHie (ClosedTypeFamily (Just eqns)) = concatM $ - [ concatMapM (pure . locOnly . getLoc) eqns + [ concatMapM (pure . locOnly . getLocA) eqns , toHie $ map go eqns ] where - go (L l ib) = TS (ResolvedScopes [mkScope l]) ib + go (L l ib) = TS (ResolvedScopes [mkScope (locA l)]) ib toHie _ = pure [] instance ToHie (RScoped (LFamilyResultSig GhcRn)) where @@ -1389,7 +1389,7 @@ instance (ToHie rhs, HasLoc rhs) instance ToHie (LInjectivityAnn GhcRn) where toHie (L span ann) = concatM $ makeNode ann span : case ann of - InjectivityAnn lhs rhs -> + InjectivityAnn _ lhs rhs -> [ toHie $ C Use lhs , toHie $ map (C Use) rhs ] @@ -1413,7 +1413,7 @@ instance ToHie (LHsDerivingClause GhcRn) where toHie (L span cl) = concatM $ makeNode cl span : case cl of HsDerivingClause _ strat (L ispan tys) -> [ toHie strat - , pure $ locOnly ispan + , pure $ locOnly (locA ispan) , toHie $ map (TS (ResolvedScopes [])) tys ] XHsDerivingClause _ -> [] @@ -1425,8 +1425,8 @@ instance ToHie (Located (DerivStrategy GhcRn)) where NewtypeStrategy _ -> [] ViaStrategy s -> [ toHie $ TS (ResolvedScopes []) s ] -instance ToHie (Located OverlapMode) where - toHie (L span _) = pure $ locOnly span +instance ToHie (LocatedA OverlapMode) where + toHie (L span _) = pure $ locOnly (locA span) instance ToHie (LConDecl GhcRn) where toHie (L span decl) = concatM $ makeNode decl span : case decl of @@ -1440,7 +1440,7 @@ instance ToHie (LConDecl GhcRn) where ] where rhsScope = combineScopes argsScope tyScope - ctxScope = maybe NoScope mkLScope ctx + ctxScope = maybe NoScope mkLScopeA ctx argsScope = condecl_scope args tyScope = mkLScope typ ConDeclH98 { con_name = name, con_ex_tvs = qvars @@ -1452,7 +1452,7 @@ instance ToHie (LConDecl GhcRn) where ] where rhsScope = combineScopes ctxScope argsScope - ctxScope = maybe NoScope mkLScope ctx + ctxScope = maybe NoScope mkLScopeA ctx argsScope = condecl_scope dets XConDecl _ -> [] where condecl_scope args = case args of @@ -1645,7 +1645,7 @@ instance ToHie (TScoped (LHsQTyVars GhcRn)) where instance ToHie (LHsContext GhcRn) where toHie (L span tys) = concatM $ - [ pure $ locOnly span + [ pure $ locOnly (locA span) , toHie tys ] @@ -1863,10 +1863,10 @@ instance ToHie (LRuleDecls GhcRn) where instance ToHie (LRuleDecl GhcRn) where toHie (L _ (XRuleDecl _)) = pure [] toHie (L span r@(HsRule _ rname _ tybndrs bndrs exprA exprB)) = concatM - [ makeNode r span + [ makeNode r (locA span) , pure $ locOnly $ getLoc rname , toHie $ fmap (tvScopes (ResolvedScopes []) scope) tybndrs - , toHie $ map (RS $ mkScope span) bndrs + , toHie $ map (RS $ mkScope (locA span)) bndrs , toHie exprA , toHie exprB ] @@ -1887,7 +1887,7 @@ instance ToHie (RScoped (LRuleBndr GhcRn)) where XRuleBndr _ -> [] instance ToHie (LImportDecl GhcRn) where - toHie (L span decl) = concatM $ makeNode decl span : case decl of + toHie (L span decl) = concatM $ makeNode decl (locA span) : case decl of ImportDecl { ideclName = name, ideclAs = as, ideclHiding = hidden } -> [ toHie $ IEC Import name , toHie $ fmap (IEC ImportAs) as @@ -1896,14 +1896,14 @@ instance ToHie (LImportDecl GhcRn) where XImportDecl _ -> [] where goIE (hiding, (L sp liens)) = concatM $ - [ pure $ locOnly sp + [ pure $ locOnly (locA sp) , toHie $ map (IEC c) liens ] where c = if hiding then ImportHiding else Import instance ToHie (IEContext (LIE GhcRn)) where - toHie (IEC c (L span ie)) = concatM $ makeNode ie span : case ie of + toHie (IEC c (L span ie)) = concatM $ makeNode ie (locA span) : case ie of IEVar _ n -> [ toHie $ IEC c n ] ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -273,7 +273,7 @@ rnImportDecl this_mod , ideclSource = want_boot, ideclSafe = mod_safe , ideclQualified = qual_style, ideclImplicit = implicit , ideclAs = as_mod, ideclHiding = imp_details })) - = setSrcSpan loc $ do + = setSrcSpan (locA loc) $ do when (isJust mb_pkg) $ do pkg_imports <- xoptM LangExt.PackageImports @@ -343,7 +343,7 @@ rnImportDecl this_mod let qual_mod_name = fmap unLoc as_mod `orElse` imp_mod_name imp_spec = ImpDeclSpec { is_mod = imp_mod_name, is_qual = qual_only, - is_dloc = loc, is_as = qual_mod_name } + is_dloc = locA loc, is_as = qual_mod_name } -- filter the imports according to the import declaration (new_imp_details, gres) <- filterImports iface imp_spec imp_details @@ -364,7 +364,7 @@ rnImportDecl this_mod let imv = ImportedModsVal { imv_name = qual_mod_name - , imv_span = loc + , imv_span = locA loc , imv_is_safe = mod_safe' , imv_is_hiding = is_hiding , imv_all_exports = potential_gres @@ -906,8 +906,8 @@ although we never look up data constructors. filterImports :: ModIface -> ImpDeclSpec -- The span for the entire import decl - -> Maybe (Bool, Located [LIE GhcPs]) -- Import spec; True => hiding - -> RnM (Maybe (Bool, Located [LIE GhcRn]), -- Import spec w/ Names + -> Maybe (Bool, LocatedA [LIE GhcPs]) -- Import spec; True => hiding + -> RnM (Maybe (Bool, LocatedA [LIE GhcRn]), -- Import spec w/ Names [GlobalRdrElt]) -- Same again, but in GRE form filterImports iface decl_spec Nothing = return (Nothing, gresFromAvails (Just imp_spec) (mi_exports iface)) @@ -967,7 +967,7 @@ filterImports iface decl_spec (Just (want_hiding, L l import_items)) lookup_lie :: LIE GhcPs -> TcRn [(LIE GhcRn, AvailInfo)] lookup_lie (L loc ieRdr) - = do (stuff, warns) <- setSrcSpan loc $ + = do (stuff, warns) <- setSrcSpan (locA loc) $ liftM (fromMaybe ([],[])) $ run_lookup (lookup_ie ieRdr) mapM_ emit_warning warns @@ -1156,7 +1156,8 @@ gresFromIE decl_spec (L loc ie, avail) prov_fn name = Just (ImpSpec { is_decl = decl_spec, is_item = item_spec }) where - item_spec = ImpSome { is_explicit = is_explicit name, is_iloc = loc } + item_spec = ImpSome { is_explicit = is_explicit name + , is_iloc = locA loc } {- @@ -1399,7 +1400,7 @@ findImportUsage imports used_gres unused_decl decl@(L loc (ImportDecl { ideclHiding = imps })) = (decl, used_gres, nameSetElemsStable unused_imps) where - used_gres = lookupSrcLoc (srcSpanEnd loc) import_usage + used_gres = lookupSrcLoc (srcSpanEnd $ locA loc) import_usage -- srcSpanEnd: see Note [The ImportMap] `orElse` [] @@ -1499,7 +1500,7 @@ warnUnusedImport flag fld_env (L loc decl, used, unused) -- Nothing used; drop entire declaration | null used - = addWarnAt (Reason flag) loc msg1 + = addWarnAt (Reason flag) (locA loc) msg1 -- Everything imported is used; nop | null unused @@ -1507,7 +1508,7 @@ warnUnusedImport flag fld_env (L loc decl, used, unused) -- Some imports are unused | otherwise - = addWarnAt (Reason flag) loc msg2 + = addWarnAt (Reason flag) (locA loc) msg2 where msg1 = vcat [ pp_herald <+> quotes pp_mod <+> is_redundant ===================================== compiler/GHC/Rename/Source.hs ===================================== @@ -244,6 +244,9 @@ addTcgDUs tcg_env dus = tcg_env { tcg_dus = tcg_dus tcg_env `plusDU` dus } rnList :: (a -> RnM (b, FreeVars)) -> [Located a] -> RnM ([Located b], FreeVars) rnList f xs = mapFvRn (wrapLocFstM f) xs +rnListA :: (a -> RnM (b, FreeVars)) -> [LocatedA a] -> RnM ([LocatedA b], FreeVars) +rnListA f xs = mapFvRn (wrapLocFstMA f) xs + {- ********************************************************* * * @@ -750,7 +753,7 @@ rnFamInstEqn doc atfi rhs_kvars ; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances] , hsib_body - = FamEqn { feqn_ext = noExtField + = FamEqn { feqn_ext = noAnn , feqn_tycon = tycon' , feqn_bndrs = bndrs' <$ mb_bndrs , feqn_pats = pats' @@ -978,7 +981,7 @@ rnSrcDerivDecl (DerivDecl _ ty mds overlap) <- rnLDerivStrategy DerivDeclCtx mds $ rnHsSigWcType BindUnlessForall DerivDeclCtx ty ; warnNoDerivStrat mds' loc - ; return (DerivDecl noExtField ty' mds' overlap, fvs) } + ; return (DerivDecl noAnn ty' mds' overlap, fvs) } where loc = getLoc $ hsib_body $ hswc_body ty rnSrcDerivDecl (XDerivDecl nec) = noExtCon nec @@ -999,7 +1002,7 @@ standaloneDerivErr rnHsRuleDecls :: RuleDecls GhcPs -> RnM (RuleDecls GhcRn, FreeVars) rnHsRuleDecls (HsRules { rds_src = src , rds_rules = rules }) - = do { (rn_rules,fvs) <- rnList rnHsRuleDecl rules + = do { (rn_rules,fvs) <- rnListA rnHsRuleDecl rules ; return (HsRules { rds_ext = noExtField , rds_src = src , rds_rules = rn_rules }, fvs) } @@ -1905,7 +1908,7 @@ rnFamDecl mb_cls (FamilyDecl { fdLName = tycon, fdTyVars = tyvars -> FamilyInfo GhcPs -> RnM (FamilyInfo GhcRn, FreeVars) rn_info (L _ fam_name) (ClosedTypeFamily (Just eqns)) = do { (eqns', fvs) - <- rnList (rnTyFamInstEqn NonAssocTyFamEqn (ClosedTyFam tycon fam_name)) + <- rnListA (rnTyFamInstEqn NonAssocTyFamEqn (ClosedTyFam tycon fam_name)) -- no class context eqns ; return (ClosedTypeFamily (Just eqns'), fvs) } @@ -1987,16 +1990,16 @@ rnInjectivityAnn :: LHsQTyVars GhcRn -- ^ Type variables declared in -> LInjectivityAnn GhcPs -- ^ Injectivity annotation -> RnM (LInjectivityAnn GhcRn) rnInjectivityAnn tvBndrs (L _ (TyVarSig _ resTv)) - (L srcSpan (InjectivityAnn injFrom injTo)) + (L srcSpan (InjectivityAnn x injFrom injTo)) = do - { (injDecl'@(L _ (InjectivityAnn injFrom' injTo')), noRnErrors) + { (injDecl'@(L _ (InjectivityAnn _ injFrom' injTo')), noRnErrors) <- askNoErrs $ bindLocalNames [hsLTyVarName resTv] $ -- The return type variable scopes over the injectivity annotation -- e.g. type family F a = (r::*) | r -> a do { injFrom' <- rnLTyVar injFrom ; injTo' <- mapM rnLTyVar injTo - ; return $ L srcSpan (InjectivityAnn injFrom' injTo') } + ; return $ L srcSpan (InjectivityAnn x injFrom' injTo') } ; let tvNames = Set.fromList $ hsAllLTyVarNames tvBndrs resName = hsLTyVarName resTv @@ -2032,12 +2035,12 @@ rnInjectivityAnn tvBndrs (L _ (TyVarSig _ resTv)) -- -- So we rename injectivity annotation like we normally would except that -- this time we expect "result" to be reported not in scope by rnLTyVar. -rnInjectivityAnn _ _ (L srcSpan (InjectivityAnn injFrom injTo)) = +rnInjectivityAnn _ _ (L srcSpan (InjectivityAnn x injFrom injTo)) = setSrcSpan srcSpan $ do (injDecl', _) <- askNoErrs $ do injFrom' <- rnLTyVar injFrom injTo' <- mapM rnLTyVar injTo - return $ L srcSpan (InjectivityAnn injFrom' injTo') + return $ L srcSpan (InjectivityAnn x injFrom' injTo') return $ injDecl' {- ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -773,7 +773,7 @@ findGlobalRdrEnv hsc_env imports (err : _, _) -> Left err } where idecls :: [LImportDecl GhcPs] - idecls = [noLoc d | IIDecl d <- imports] + idecls = [noLocA d | IIDecl d <- imports] imods :: [ModuleName] imods = [m | IIModule m <- imports] ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -124,6 +124,9 @@ setL loc = CvtM (\_ _ -> Right (loc, ())) returnL :: a -> CvtM (Located a) returnL x = CvtM (\_ loc -> Right (loc, L loc x)) +returnLA :: a -> CvtM (LocatedA a) +returnLA x = CvtM (\_ loc -> Right (loc, L (noAnnSrcSpan loc) x)) + returnJustL :: a -> CvtM (Maybe (Located a)) returnJustL = fmap Just . returnL @@ -293,7 +296,8 @@ cvtDec (InstanceD o ctxt ty decs) , cid_binds = binds' , cid_sigs = Hs.mkClassOpSigs sigs' , cid_tyfam_insts = ats', cid_datafam_insts = adts' - , cid_overlap_mode = fmap (L loc . overlap) o } } + , cid_overlap_mode + = fmap (L (noAnnSrcSpan loc) . overlap) o } } where overlap pragma = case pragma of @@ -329,7 +333,7 @@ cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) ; returnJustL $ InstD noExtField $ DataFamInstD { dfid_ext = noAnn , dfid_inst = DataFamInstDecl { dfid_eqn = mkHsImplicitBndrs $ - FamEqn { feqn_ext = noExtField + FamEqn { feqn_ext = noAnn , feqn_tycon = tc' , feqn_bndrs = bndrs' , feqn_pats = typats' @@ -349,7 +353,7 @@ cvtDec (NewtypeInstD ctxt bndrs tys ksig constr derivs) ; returnJustL $ InstD noExtField $ DataFamInstD { dfid_ext = noAnn , dfid_inst = DataFamInstDecl { dfid_eqn = mkHsImplicitBndrs $ - FamEqn { feqn_ext = noExtField + FamEqn { feqn_ext = noAnn , feqn_tycon = tc' , feqn_bndrs = bndrs' , feqn_pats = typats' @@ -387,7 +391,7 @@ cvtDec (TH.StandaloneDerivD ds cxt ty) ; (L loc ty') <- cvtType ty ; let inst_ty' = mkHsQualTy cxt loc cxt' $ L loc ty' ; returnJustL $ DerivD noExtField $ - DerivDecl { deriv_ext =noExtField + DerivDecl { deriv_ext = noAnn , deriv_strategy = ds' , deriv_type = mkLHsSigWcType inst_ty' , deriv_overlap_mode = Nothing } } @@ -440,8 +444,8 @@ cvtTySynEqn (TySynEqn mb_bndrs lhs rhs) ConT nm -> do { nm' <- tconNameL nm ; rhs' <- cvtType rhs ; let args' = map wrap_tyarg args - ; returnL $ mkHsImplicitBndrs - $ FamEqn { feqn_ext = noExtField + ; returnLA $ mkHsImplicitBndrs + $ FamEqn { feqn_ext = noAnn , feqn_tycon = nm' , feqn_bndrs = mb_bndrs' , feqn_pats = args' @@ -450,8 +454,8 @@ cvtTySynEqn (TySynEqn mb_bndrs lhs rhs) InfixT t1 nm t2 -> do { nm' <- tconNameL nm ; args' <- mapM cvtType [t1,t2] ; rhs' <- cvtType rhs - ; returnL $ mkHsImplicitBndrs - $ FamEqn { feqn_ext = noExtField + ; returnLA $ mkHsImplicitBndrs + $ FamEqn { feqn_ext = noAnn , feqn_tycon = nm' , feqn_bndrs = mb_bndrs' , feqn_pats = @@ -697,7 +701,7 @@ cvtForD (ImportF callconv safety from nm ty) mk_imp impspec = do { nm' <- vNameL nm ; ty' <- cvtType ty - ; return (ForeignImport { fd_i_ext = noExtField + ; return (ForeignImport { fd_i_ext = noAnn , fd_name = nm' , fd_sig_ty = mkLHsSigType ty' , fd_fi = impspec }) @@ -714,7 +718,7 @@ cvtForD (ExportF callconv as nm ty) (mkFastString as) (cvt_conv callconv))) (noLoc (SourceText as)) - ; return $ ForeignExport { fd_e_ext = noExtField + ; return $ ForeignExport { fd_e_ext = noAnn , fd_name = nm' , fd_sig_ty = mkLHsSigType ty' , fd_fe = e } } @@ -777,8 +781,8 @@ cvtPragmaD (RuleP nm ty_bndrs tm_bndrs lhs rhs phases) ; returnJustL $ Hs.RuleD noExtField $ HsRules { rds_ext = noAnn , rds_src = SourceText "{-# RULES" - , rds_rules = [noLoc $ - HsRule { rd_ext = noExtField + , rds_rules = [noLocA $ + HsRule { rd_ext = noAnn , rd_name = (noLoc (quotedSourceText nm,nm')) , rd_act = act , rd_tyvs = ty_bndrs' @@ -1353,7 +1357,7 @@ cvtRole TH.InferR = Nothing cvtContext :: PprPrec -> TH.Cxt -> CvtM (LHsContext GhcPs) cvtContext p tys = do { preds' <- mapM cvtPred tys - ; parenthesizeHsContext p <$> returnL preds' } + ; parenthesizeHsContext p <$> returnLA preds' } cvtPred :: TH.Pred -> CvtM (LHsType GhcPs) cvtPred = cvtType @@ -1688,7 +1692,7 @@ cvtInjectivityAnnotation :: TH.InjectivityAnn cvtInjectivityAnnotation (TH.InjectivityAnn annLHS annRHS) = do { annLHS' <- tNameL annLHS ; annRHS' <- mapM tNameL annRHS - ; returnL (Hs.InjectivityAnn annLHS' annRHS') } + ; returnL (Hs.InjectivityAnn noAnn annLHS' annRHS') } cvtPatSynSigTy :: TH.Type -> CvtM (LHsType GhcPs) -- pattern synonym types are of peculiar shapes, which is why we treat @@ -1698,7 +1702,7 @@ cvtPatSynSigTy (ForallT univs reqs (ForallT exis provs ty)) | null exis, null provs = cvtType (ForallT univs reqs ty) | null univs, null reqs = do { l <- getL ; ty' <- cvtType (ForallT exis provs ty) - ; return $ L l (HsQualTy { hst_ctxt = L l [] + ; return $ L l (HsQualTy { hst_ctxt = L (noAnnSrcSpan l) [] , hst_xqual = noAnn , hst_body = ty' }) } | null reqs = do { l <- getL @@ -1709,7 +1713,7 @@ cvtPatSynSigTy (ForallT univs reqs (ForallT exis provs ty)) , hst_bndrs = univs' , hst_xforall = noAnn , hst_body = L l cxtTy } - cxtTy = HsQualTy { hst_ctxt = L l [] + cxtTy = HsQualTy { hst_ctxt = L (noAnnSrcSpan l) [] , hst_xqual = noAnn , hst_body = ty' } ; return $ L l forTy } ===================================== compiler/main/HeaderInfo.hs ===================================== @@ -125,18 +125,19 @@ mkPrelImports this_mod loc implicit_prelude import_decls <- import_decls , unLoc mod == pRELUDE_NAME ] + loc' = noAnnSrcSpan loc preludeImportDecl :: LImportDecl GhcPs preludeImportDecl - = L loc $ ImportDecl { ideclExt = noAnn, - ideclSourceSrc = NoSourceText, - ideclName = L loc pRELUDE_NAME, - ideclPkgQual = Nothing, - ideclSource = False, - ideclSafe = False, -- Not a safe import - ideclQualified = NotQualified, - ideclImplicit = True, -- Implicit! - ideclAs = Nothing, - ideclHiding = Nothing } + = L loc' $ ImportDecl { ideclExt = noAnn, + ideclSourceSrc = NoSourceText, + ideclName = L loc pRELUDE_NAME, + ideclPkgQual = Nothing, + ideclSource = False, + ideclSafe = False, -- Not a safe import + ideclQualified = NotQualified, + ideclImplicit = True, -- Implicit! + ideclAs = Nothing, + ideclHiding = Nothing } -------------------------------------------------------------- -- Get options ===================================== compiler/main/HscStats.hs ===================================== @@ -22,7 +22,7 @@ import Data.Char -- | Source Statistics ppSourceStats :: Bool -> Located HsModule -> SDoc -ppSourceStats short (L _ (HsModule _ exports imports ldecls _ _)) +ppSourceStats short (L _ (HsModule _ _ exports imports ldecls _ _)) = (if short then hcat else vcat) (map pp_val [("ExportAll ", export_all), -- 1 if no export list ===================================== compiler/parser/Lexer.x ===================================== @@ -2124,7 +2124,7 @@ data PState = PState { -- locations of 'noise' tokens in the source, so that users of -- the GHC API can do source to source conversions. -- See note [Api annotations] in ApiAnnotation.hs - annotations :: [(ApiAnnKey,[RealSrcSpan])], + -- AZ annotations :: [(ApiAnnKey,[RealSrcSpan])], eof_pos :: Maybe RealSrcSpan, comment_q :: [RealLocated AnnotationComment], annotations_comments :: [(RealSrcSpan,[RealLocated AnnotationComment])] @@ -2606,7 +2606,7 @@ mkPStatePure options buf loc = alr_context = [], alr_expecting_ocurly = Nothing, alr_justClosedExplicitLetBlock = False, - annotations = [], + -- AZ annotations = [], eof_pos = Nothing, comment_q = [], annotations_comments = [] @@ -2692,7 +2692,7 @@ instance MonadP P where getBit ext = P $ \s -> let b = ext `xtest` pExtsBitmap (options s) in b `seq` POk s b addAnnotation (RealSrcSpan l _) a (RealSrcSpan v _) = do - addAnnotationOnly l a v + -- AZ addAnnotationOnly l a v _ <- allocateCommentsP l return () addAnnotation _ _ _ = return () @@ -3236,10 +3236,12 @@ data AddApiAnn = AddApiAnn AnnKeywordId SrcSpan deriving (Data,Show,Eq) instance Outputable AddApiAnn where ppr (AddApiAnn kw ss) = text "AddApiAnn" <+> ppr kw <+> ppr ss +{- AZ addAnnotationOnly :: RealSrcSpan -> AnnKeywordId -> RealSrcSpan -> P () addAnnotationOnly l a v = P $ \s -> POk s { annotations = ((l,a), [v]) : annotations s } () +-} -- |Given a 'SrcSpan' that surrounds a 'HsPar' or 'HsParTy', generate -- 'AddApiAnn' values for the opening and closing bordering on the start ===================================== compiler/parser/Parser.y ===================================== @@ -725,12 +725,12 @@ unitdecl :: { LHsUnitDecl PackageName } False -> HsSrcFile True -> HsBootFile) $4 - (Just $ sL1 $2 (HsModule (Just $4) $6 (fst $ snd $8) (snd $ snd $8) $5 $1)) } + (Just $ sL1 $2 (HsModule noAnn (Just $4) $6 (fst $ snd $8) (snd $ snd $8) $5 $1)) } | maybedocheader 'signature' modid maybemodwarning maybeexports 'where' body { sL1 $2 $ DeclD HsigFile $3 - (Just $ sL1 $2 (HsModule (Just $3) $5 (fst $ snd $7) (snd $ snd $7) $4 $1)) } + (Just $ sL1 $2 (HsModule noAnn (Just $3) $5 (fst $ snd $7) (snd $ snd $7) $4 $1)) } -- NB: MUST have maybedocheader here, otherwise shift-reduce conflict -- will prevent us from parsing both forms. | maybedocheader 'module' maybe_src modid @@ -761,23 +761,20 @@ unitdecl :: { LHsUnitDecl PackageName } signature :: { Located HsModule } : maybedocheader 'signature' modid maybemodwarning maybeexports 'where' body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 (fst $ snd $7) - (snd $ snd $7) $4 $1) - ) - ([mj AnnSignature $2, mj AnnWhere $6] ++ fst $7) } + acs (\cs -> L loc (HsModule (ApiAnn ([mj AnnSignature $2, mj AnnWhere $6] ++ fst $7) cs) + (Just $3) $5 (fst $ snd $7) + (snd $ snd $7) $4 $1) )} module :: { Located HsModule } : maybedocheader 'module' modid maybemodwarning maybeexports 'where' body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 (fst $ snd $7) - (snd $ snd $7) $4 $1) - ) - ([mj AnnModule $2, mj AnnWhere $6] ++ fst $7) } + acs (\cs -> L loc (HsModule (ApiAnn ([mj AnnModule $2, mj AnnWhere $6] ++ fst $7) cs) + (Just $3) $5 (fst $ snd $7) + (snd $ snd $7) $4 $1) ) } | body2 {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule Nothing Nothing - (fst $ snd $1) (snd $ snd $1) Nothing Nothing)) - (fst $1) } + acs (\cs -> L loc (HsModule (ApiAnn (fst $1) cs) Nothing Nothing + (fst $ snd $1) (snd $ snd $1) Nothing Nothing)) } maybedocheader :: { Maybe LHsDocString } : moduleheader { $1 } @@ -789,13 +786,13 @@ missing_module_keyword :: { () } implicit_top :: { () } : {- empty -} {% pushModuleContext } -maybemodwarning :: { Maybe (Located WarningTxt) } +maybemodwarning :: { Maybe (LocatedA WarningTxt) } : '{-# DEPRECATED' strings '#-}' - {% ajs (\_ -> sLL $1 $> $ DeprecatedTxt (sL1 $1 (getDEPRECATED_PRAGs $1)) (snd $ unLoc $2)) - (mo $1:mc $3: (fst $ unLoc $2)) } + {% fmap Just $ amsr (sLL $1 $> $ DeprecatedTxt (sL1 $1 (getDEPRECATED_PRAGs $1)) (snd $ unLoc $2)) + (mo $1:mc $3: (fst $ unLoc $2))} | '{-# WARNING' strings '#-}' - {% ajs (\_ -> sLL $1 $> $ WarningTxt (sL1 $1 (getWARNING_PRAGs $1)) (snd $ unLoc $2)) - (mo $1:mc $3 : (fst $ unLoc $2)) } + {% fmap Just $ amsr (sLL $1 $> $ WarningTxt (sL1 $1 (getWARNING_PRAGs $1)) (snd $ unLoc $2)) + (mo $1:mc $3 : (fst $ unLoc $2))} | {- empty -} { Nothing } body :: { ([AddApiAnn] @@ -826,15 +823,17 @@ top1 :: { ([LImportDecl GhcPs], [LHsDecl GhcPs]) } header :: { Located HsModule } : maybedocheader 'module' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 $7 [] $4 $1 - )) [mj AnnModule $2,mj AnnWhere $6] } + acs (\cs -> L loc (HsModule (ApiAnn [mj AnnModule $2,mj AnnWhere $6] cs) + (Just $3) $5 $7 [] $4 $1 + )) } | maybedocheader 'signature' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> - ams (\_ -> L loc (HsModule (Just $3) $5 $7 [] $4 $1 - )) [mj AnnModule $2,mj AnnWhere $6] } + acs (\cs -> L loc (HsModule (ApiAnn [mj AnnModule $2,mj AnnWhere $6] cs) + (Just $3) $5 $7 [] $4 $1 + )) } | header_body2 {% fileSrcSpan >>= \ loc -> - return (L loc (HsModule Nothing Nothing $1 [] Nothing + return (L loc (HsModule noAnn Nothing Nothing $1 [] Nothing Nothing)) } header_body :: { [LImportDecl GhcPs] } @@ -855,21 +854,28 @@ header_top_importdecls :: { [LImportDecl GhcPs] } ----------------------------------------------------------------------------- -- The Export List -maybeexports :: { (Maybe (Located [LIE GhcPs])) } - : '(' exportlist ')' {% amsL (comb2 $1 $>) [mop $1,mcp $3] >> - return (Just (sLL $1 $> (fromOL $2))) } +maybeexports :: { (Maybe (LocatedA [LIE GhcPs])) } + : '(' exportlist ')' {% fmap Just $ amsr (sLL $1 $> (fromOL $2)) [mop $1,mcp $3] } | {- empty -} { Nothing } exportlist :: { OrdList (LIE GhcPs) } - : expdoclist ',' expdoclist {% addAnnotation (oll $1) AnnComma (gl $2) - >> return ($1 `appOL` $3) } + : expdoclist ',' expdoclist {% if isNilOL $1 + then return ($1 `appOL` $3) + else case unsnocOL $1 of + (hs,t) -> do + t' <- addAnnotationA t AnnComma (gl $2) + return (snocOL hs t' `appOL` $3) } | exportlist1 { $1 } exportlist1 :: { OrdList (LIE GhcPs) } : expdoclist export expdoclist ',' exportlist1 - {% (addAnnotation (oll ($1 `appOL` $2 `appOL` $3)) - AnnComma (gl $4) ) >> - return ($1 `appOL` $2 `appOL` $3 `appOL` $5) } + {% let ls = $1 `appOL` $2 `appOL` $3 + in if isNilOL ls + then return (ls `appOL` $5) + else case unsnocOL ls of + (hs, t) -> do + t' <- addAnnotationA t AnnComma (gl $4) + return (snocOL hs t' `appOL` $5)} | expdoclist export expdoclist { $1 `appOL` $2 `appOL` $3 } | expdoclist { $1 } @@ -878,20 +884,19 @@ expdoclist :: { OrdList (LIE GhcPs) } | {- empty -} { nilOL } exp_doc :: { OrdList (LIE GhcPs) } - : docsection { unitOL (sL1 $1 (case (unLoc $1) of (n, doc) -> IEGroup noExtField n doc)) } - | docnamed { unitOL (sL1 $1 (IEDocNamed noExtField ((fst . unLoc) $1))) } - | docnext { unitOL (sL1 $1 (IEDoc noExtField (unLoc $1))) } - + : docsection { unitOL (sL1a $1 (case (unLoc $1) of (n, doc) -> IEGroup noExtField n doc)) } + | docnamed { unitOL (sL1a $1 (IEDocNamed noExtField ((fst . unLoc) $1))) } + | docnext { unitOL (sL1a $1 (IEDoc noExtField (unLoc $1))) } -- No longer allow things like [] and (,,,) to be exported -- They are built in syntax, always available export :: { OrdList (LIE GhcPs) } : qcname_ext export_subspec {% mkModuleImpExp $1 (snd $ unLoc $2) - >>= \ie -> amsu (\_ -> sLL $1 $> ie) (fst $ unLoc $2) } - | 'module' modid {% amsu (\cs -> sLL $1 $> (IEModuleContents (ApiAnn [mj AnnModule $1] cs) $2)) - [mj AnnModule $1] } - | 'pattern' qcon {% amsu (\cs -> sLLlA $1 $> (IEVar (ApiAnn [mj AnnPattern $1] cs) (sLLlA $1 $> (IEPattern $2)))) - [mj AnnPattern $1] } + >>= \ie -> fmap unitOL (amsr (sLL $1 $> ie) (fst $ unLoc $2)) } + | 'module' modid {% fmap (unitOL . reLocA) (ams (\cs -> sLL $1 $> (IEModuleContents (ApiAnn [mj AnnModule $1] cs) $2)) + [mj AnnModule $1]) } + | 'pattern' qcon {% fmap (unitOL . reLocA) (ams (\cs -> sLLlA $1 $> (IEVar (ApiAnn [mj AnnPattern $1] cs) (sLLlA $1 $> (IEPattern $2)))) + [mj AnnPattern $1]) } export_subspec :: { Located ([AddApiAnn],ImpExpSubSpec) } : {- empty -} { sL0 ([],ImpExpAbs) } @@ -925,9 +930,9 @@ qcname_ext_w_wildcard :: { Located ([AddApiAnn], Located ImpExpQcSpec) } qcname_ext :: { Located ImpExpQcSpec } : qcname { sL1A $1 (ImpExpQcName $1) } - | 'type' oqtycon {% do { n <- mkTypeImpExp $2 - ; ams (\_ -> sLLlA $1 $> (ImpExpQcType n)) - [mj AnnType $1] } } + | 'type' oqtycon {% do { n' <- reA $1 $2 [mj AnnType $1] + ; n <- mkTypeImpExp n' + ; return $ sLLlA $1 $> (ImpExpQcType n) }} qcname :: { LocatedA RdrName } -- Variable or type constructor : qvar { $1 } -- Things which look like functions @@ -961,7 +966,7 @@ importdecls importdecls_semi :: { [LImportDecl GhcPs] } importdecls_semi : importdecls_semi importdecl semis1 - {% ams (\_ -> $2) $3 >> return ($2 : $1) } + {% amsA $2 $3 >> return ($2 : $1) } | {- empty -} { [] } importdecl :: { LImportDecl GhcPs } @@ -971,8 +976,7 @@ importdecl :: { LImportDecl GhcPs } ; let anns = (mj AnnImport $1 : fst (fst $2) ++ fst $3 ++ fmap (mj AnnQualified) (maybeToList $4) ++ fst $5 ++ fmap (mj AnnQualified) (maybeToList $7) ++ fst $8) - ; cs <- allocateCommentsS (comb4 $1 $6 (snd $8) $9) - ; ams (\_ -> L (comb4 $1 $6 (snd $8) $9) $ + ; fmap reLocA $ ams (\cs -> L (comb4 $1 $6 (snd $8) $9) $ ImportDecl { ideclExt = ApiAnn anns cs , ideclSourceSrc = snd $ fst $2 , ideclName = $6, ideclPkgQual = snd $5 @@ -1014,20 +1018,20 @@ maybeas :: { ([AddApiAnn],Located (Maybe (Located ModuleName))) } ,sLL $1 $> (Just $2)) } | {- empty -} { ([],noLoc Nothing) } -maybeimpspec :: { Located (Maybe (Bool, Located [LIE GhcPs])) } +maybeimpspec :: { Located (Maybe (Bool, LocatedA [LIE GhcPs])) } : impspec {% let (b, ie) = unLoc $1 in checkImportSpec ie >>= \checkedIe -> return (L (gl $1) (Just (b, checkedIe))) } | {- empty -} { noLoc Nothing } -impspec :: { Located (Bool, Located [LIE GhcPs]) } - : '(' exportlist ')' {% ams (\_ -> sLL $1 $> (False, - sLL $1 $> $ fromOL $2)) - [mop $1,mcp $3] } - | 'hiding' '(' exportlist ')' {% ams (\_ -> sLL $1 $> (True, - sLL $1 $> $ fromOL $3)) - [mj AnnHiding $1,mop $2,mcp $4] } +impspec :: { Located (Bool, LocatedA [LIE GhcPs]) } + : '(' exportlist ')' {% do { es <- amsr (sLL $1 $> $ fromOL $2) + [mop $1,mcp $3] + ; return $ sLL $1 $> (False, es)} } + | 'hiding' '(' exportlist ')' {% do { es <- amsr (sLL $1 $> $ fromOL $3) + [mj AnnHiding $1,mop $2,mcp $4] + ; return $ sLL $1 $> (True, es)} } ----------------------------------------------------------------------------- -- Fixity Declarations @@ -1043,8 +1047,10 @@ infix :: { Located FixityDirection } | 'infixr' { sL1 $1 InfixR } ops :: { Located (OrdList (LocatedA RdrName)) } - : ops ',' op {% addAnnotation (ollA $ unLoc $1) AnnComma (gl $2) >> - return (sLLlA $1 $> ((unLoc $1) `appOL` unitOL $3))} + : ops ',' op {% case unsnocOL (unLoc $1) of + (hs,t) -> do + t' <- addAnnotationA t AnnComma (gl $2) + return (sLLlA $1 $> (snocOL hs t' `appOL` unitOL $3)) } | op { sL1A $1 (unitOL $1) } ----------------------------------------------------------------------------- @@ -1056,7 +1062,7 @@ topdecls :: { OrdList (LHsDecl GhcPs) } -- May have trailing semicolons, can be empty topdecls_semi :: { OrdList (LHsDecl GhcPs) } - : topdecls_semi topdecl semis1 {% ams (\_ -> $2) $3 >> return ($1 `snocOL` $2) } + : topdecls_semi topdecl semis1 {% amsr $2 $3 >> return ($1 `snocOL` $2) } | {- empty -} { nilOL } topdecl :: { LHsDecl GhcPs } @@ -1066,17 +1072,12 @@ topdecl :: { LHsDecl GhcPs } | inst_decl { sL1 $1 (InstD noExtField (unLoc $1)) } | stand_alone_deriving { sLL $1 $> (DerivD noExtField (unLoc $1)) } | role_annot { sL1 $1 (RoleAnnotD noExtField (unLoc $1)) } - | 'default' '(' comma_types0 ')' {% ams (\cs -> sLL $1 $> (DefD noExtField (DefaultDecl (ApiAnn [mj AnnDefault $1,mop $2,mcp $4] cs) $3))) - [mj AnnDefault $1 - ,mop $2,mcp $4] } - | 'foreign' fdecl {% ams (\_ -> sLL $1 $> (snd $ unLoc $2)) - (mj AnnForeign $1:(fst $ unLoc $2)) } - | '{-# DEPRECATED' deprecations '#-}' {% ams (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getDEPRECATED_PRAGs $1) (fromOL $2))) - [mo $1,mc $3] } - | '{-# WARNING' warnings '#-}' {% ams (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getWARNING_PRAGs $1) (fromOL $2))) - [mo $1,mc $3] } - | '{-# RULES' rules '#-}' {% ams (\cs -> sLL $1 $> $ RuleD noExtField (HsRules (ApiAnn [mo $1,mc $3] cs) (getRULES_PRAGs $1) (fromOL $2))) - [mo $1,mc $3] } + | 'default' '(' comma_types0 ')' {% acs (\cs -> sLL $1 $> + (DefD noExtField (DefaultDecl (ApiAnn [mj AnnDefault $1,mop $2,mcp $4] cs) $3))) } + | 'foreign' fdecl {% acs (\cs -> sLL $1 $> ((snd $ unLoc $2) (ApiAnn (mj AnnForeign $1:(fst $ unLoc $2)) cs))) } + | '{-# DEPRECATED' deprecations '#-}' {% acs (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getDEPRECATED_PRAGs $1) (fromOL $2))) } + | '{-# WARNING' warnings '#-}' {% acs (\cs -> sLL $1 $> $ WarningD noExtField (Warnings (ApiAnn [mo $1,mc $3] cs) (getWARNING_PRAGs $1) (fromOL $2))) } + | '{-# RULES' rules '#-}' {% acs (\cs -> sLL $1 $> $ RuleD noExtField (HsRules (ApiAnn [mo $1,mc $3] cs) (getRULES_PRAGs $1) (reverse $2))) } | annotation { $1 } | decl_no_th { $1 } @@ -1091,8 +1092,7 @@ topdecl :: { LHsDecl GhcPs } -- cl_decl :: { LTyClDecl GhcPs } : 'class' tycl_hdr fds where_cls - {% amms (mkClassDecl (comb4 $1 $2 $3 $4) $2 $3 (snd $ unLoc $4) - (ApiAnn (mj AnnClass $1:(fst $ unLoc $3)++(fst $ unLoc $4)) noCom)) + {% mkClassDecl (comb4 $1 $2 $3 $4) $2 $3 (snd $ unLoc $4) (mj AnnClass $1:(fst $ unLoc $3)++(fst $ unLoc $4)) } -- Type declarations (toplevel) @@ -1107,63 +1107,59 @@ ty_decl :: { LTyClDecl GhcPs } -- -- Note the use of type for the head; this allows -- infix type constructors to be declared - {% amms (mkTySynonym (comb2 $1 $4) $2 $4 - (ApiAnn [mj AnnType $1,mj AnnEqual $3] noCom)) - [mj AnnType $1,mj AnnEqual $3] } + {% mkTySynonym (comb2 $1 $4) $2 $4 [mj AnnType $1,mj AnnEqual $3] } -- type family declarations | 'type' 'family' type opt_tyfam_kind_sig opt_injective_info where_type_family -- Note the use of type for the head; this allows -- infix type constructors to be declared - {% amms (mkFamDecl (comb4 $1 $3 $4 $5) (snd $ unLoc $6) $3 + {% mkFamDecl (comb4 $1 $3 $4 $5) (snd $ unLoc $6) $3 (snd $ unLoc $4) (snd $ unLoc $5) - (ApiAnn (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4) - ++ (fst $ unLoc $5) ++ (fst $ unLoc $6)) noCom)) - (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4) - ++ (fst $ unLoc $5) ++ (fst $ unLoc $6)) } + (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4) + ++ (fst $ unLoc $5) ++ (fst $ unLoc $6)) } -- ordinary data type or newtype declaration | data_or_newtype capi_ctype tycl_hdr constrs maybe_derivings - {% amms (mkTyData (comb4 $1 $3 $4 $5) (snd $ unLoc $1) $2 $3 + {% mkTyData (comb4 $1 $3 $4 $5) (snd $ unLoc $1) $2 $3 Nothing (reverse (snd $ unLoc $4)) (fmap reverse $5) - (ApiAnn ((fst $ unLoc $1):(fst $ unLoc $4)) noCom)) + ((fst $ unLoc $1):(fst $ unLoc $4)) } -- We need the location on tycl_hdr in case -- constrs and deriving are both empty - ((fst $ unLoc $1):(fst $ unLoc $4)) } -- ordinary GADT declaration | data_or_newtype capi_ctype tycl_hdr opt_kind_sig gadt_constrlist maybe_derivings - {% amms (mkTyData (comb4 $1 $3 $5 $6) (snd $ unLoc $1) $2 $3 + {% mkTyData (comb4 $1 $3 $5 $6) (snd $ unLoc $1) $2 $3 (snd $ unLoc $4) (snd $ unLoc $5) (fmap reverse $6) - (ApiAnn ((fst $ unLoc $1):(fst $ unLoc $4)++(fst $ unLoc $5)) noCom)) + ((fst $ unLoc $1):(fst $ unLoc $4)++(fst $ unLoc $5)) } -- We need the location on tycl_hdr in case -- constrs and deriving are both empty - ((fst $ unLoc $1):(fst $ unLoc $4)++(fst $ unLoc $5)) } -- data/newtype family | 'data' 'family' type opt_datafam_kind_sig - {% amms (mkFamDecl (comb3 $1 $2 $4) DataFamily $3 + {% mkFamDecl (comb3 $1 $2 $4) DataFamily $3 (snd $ unLoc $4) Nothing - (ApiAnn (mj AnnData $1:mj AnnFamily $2:(fst $ unLoc $4)) noCom)) - (mj AnnData $1:mj AnnFamily $2:(fst $ unLoc $4)) } + (mj AnnData $1:mj AnnFamily $2:(fst $ unLoc $4)) } -- standalone kind signature standalone_kind_sig :: { LStandaloneKindSig GhcPs } : 'type' sks_vars '::' ktypedoc - {% amms (mkStandaloneKindSig (comb2 $1 $4) $2 $4 - (ApiAnn [mj AnnType $1,mu AnnDcolon $3] noCom)) - [mj AnnType $1,mu AnnDcolon $3] } + {% mkStandaloneKindSig (comb2 $1 $4) $2 $4 + [mj AnnType $1,mu AnnDcolon $3]} -- See also: sig_vars sks_vars :: { Located [LocatedA RdrName] } -- Returned in reverse order : sks_vars ',' oqtycon - {% addAnnotation (glA $ head $ unLoc $1) AnnComma (gl $2) >> - return (sLLlA $1 $> ($3 : unLoc $1)) } + -- {% addAnnotation (glA $ head $ unLoc $1) AnnComma (gl $2) >> + -- return (sLLlA $1 $> ($3 : unLoc $1)) } + {% case unLoc $1 of + (h:t) -> do + h' <- addAnnotationA h AnnComma (gl $2) + return (sLLlA $1 $> ($3 : h' : t)) } | oqtycon { sL1A $1 [$1] } inst_decl :: { LInstDecl GhcPs } @@ -1177,68 +1173,57 @@ inst_decl :: { LInstDecl GhcPs } , cid_tyfam_insts = ats , cid_overlap_mode = $2 , cid_datafam_insts = adts } - ; ams (\cs -> L (comb3 $1 (hsSigType $3) $4) (ClsInstD { cid_d_ext = noExtField, cid_inst = cid cs })) - anns } } + ; acs (\cs -> L (comb3 $1 (hsSigType $3) $4) + (ClsInstD { cid_d_ext = noExtField, cid_inst = cid cs })) + } } -- type instance declarations | 'type' 'instance' ty_fam_inst_eqn - {% ams (\_ -> $3) (fst $ unLoc $3) - >> amms (mkTyFamInst (comb2 $1 $3) (snd $ unLoc $3) - (ApiAnn (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) noCom)) - (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) } + {% mkTyFamInst (comb2A $1 $3) (unLoc $3) + (mj AnnType $1:mj AnnInstance $2:[]) } -- data/newtype instance declaration | data_or_newtype 'instance' capi_ctype tycl_hdr_inst constrs maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) + {% mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) Nothing (reverse (snd $ unLoc $5)) (fmap reverse $6) - (ApiAnn ((fst $ unLoc $1):mj AnnInstance $2:(fst $ unLoc $4)++(fst $ unLoc $5)) noCom)) - ((fst $ unLoc $1):mj AnnInstance $2:(fst $ unLoc $4)++(fst $ unLoc $5)) } + ((fst $ unLoc $1):mj AnnInstance $2:(fst $ unLoc $4)++(fst $ unLoc $5)) } -- GADT instance declaration | data_or_newtype 'instance' capi_ctype tycl_hdr_inst opt_kind_sig gadt_constrlist maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 (snd $ unLoc $4) + {% mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 (snd $ unLoc $4) (snd $ unLoc $5) (snd $ unLoc $6) (fmap reverse $7) - (ApiAnn ((fst $ unLoc $1):mj AnnInstance $2 - :(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) noCom)) - ((fst $ unLoc $1):mj AnnInstance $2 + ((fst $ unLoc $1):mj AnnInstance $2 :(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) } -overlap_pragma :: { Maybe (Located OverlapMode) } - : '{-# OVERLAPPABLE' '#-}' {% ajs (\_ -> sLL $1 $> (Overlappable (getOVERLAPPABLE_PRAGs $1))) +overlap_pragma :: { Maybe (LocatedA OverlapMode) } + : '{-# OVERLAPPABLE' '#-}' {% fmap Just $ amsr (sLL $1 $> (Overlappable (getOVERLAPPABLE_PRAGs $1))) [mo $1,mc $2] } - | '{-# OVERLAPPING' '#-}' {% ajs (\_ -> sLL $1 $> (Overlapping (getOVERLAPPING_PRAGs $1))) + | '{-# OVERLAPPING' '#-}' {% fmap Just $ amsr (sLL $1 $> (Overlapping (getOVERLAPPING_PRAGs $1))) [mo $1,mc $2] } - | '{-# OVERLAPS' '#-}' {% ajs (\_ -> sLL $1 $> (Overlaps (getOVERLAPS_PRAGs $1))) + | '{-# OVERLAPS' '#-}' {% fmap Just $ amsr (sLL $1 $> (Overlaps (getOVERLAPS_PRAGs $1))) [mo $1,mc $2] } - | '{-# INCOHERENT' '#-}' {% ajs (\_ -> sLL $1 $> (Incoherent (getINCOHERENT_PRAGs $1))) + | '{-# INCOHERENT' '#-}' {% fmap Just $ amsr (sLL $1 $> (Incoherent (getINCOHERENT_PRAGs $1))) [mo $1,mc $2] } | {- empty -} { Nothing } deriv_strategy_no_via :: { LDerivStrategy GhcPs } - : 'stock' {% ams (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) - [mj AnnStock $1] } - | 'anyclass' {% ams (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) - [mj AnnAnyclass $1] } - | 'newtype' {% ams (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) - [mj AnnNewtype $1] } + : 'stock' {% acs (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) } + | 'anyclass' {% acs (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) } + | 'newtype' {% acs (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) } deriv_strategy_via :: { LDerivStrategy GhcPs } - : 'via' type {% ams (\cs -> sLL $1 $> (ViaStrategy (XViaStrategyPs (ApiAnn [mj AnnVia $1] cs) - (mkLHsSigType $2)))) - [mj AnnVia $1] } + : 'via' type {% acs (\cs -> sLL $1 $> (ViaStrategy (XViaStrategyPs (ApiAnn [mj AnnVia $1] cs) + (mkLHsSigType $2)))) } deriv_standalone_strategy :: { Maybe (LDerivStrategy GhcPs) } - : 'stock' {% ajs (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) - [mj AnnStock $1] } - | 'anyclass' {% ajs (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) - [mj AnnAnyclass $1] } - | 'newtype' {% ajs (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) - [mj AnnNewtype $1] } + : 'stock' {% fmap Just $ acs (\cs -> sL1 $1 (StockStrategy (ApiAnn [mj AnnStock $1] cs))) } + | 'anyclass' {% fmap Just $ acs (\cs -> sL1 $1 (AnyclassStrategy (ApiAnn [mj AnnAnyclass $1] cs))) } + | 'newtype' {% fmap Just $ acs (\cs -> sL1 $1 (NewtypeStrategy (ApiAnn [mj AnnNewtype $1] cs))) } | deriv_strategy_via { Just $1 } | {- empty -} { Nothing } @@ -1251,8 +1236,7 @@ opt_injective_info :: { Located ([AddApiAnn], Maybe (LInjectivityAnn GhcPs)) } injectivity_cond :: { LInjectivityAnn GhcPs } : tyvarid '->' inj_varids - {% ams (\_ -> sLLAl $1 $> (InjectivityAnn $1 (reverse (unLoc $3)))) - [mu AnnRarrow $2] } + {% acs (\cs -> sLLAl $1 $> (InjectivityAnn (ApiAnn [mu AnnRarrow $2] cs) $1 (reverse (unLoc $3)))) } inj_varids :: { Located [LocatedA RdrName] } : inj_varids tyvarid { sLLlA $1 $> ($2 : unLoc $1) } @@ -1278,26 +1262,28 @@ ty_fam_inst_eqn_list :: { Located ([AddApiAnn],Maybe [LTyFamInstEqn GhcPs]) } ty_fam_inst_eqns :: { Located [LTyFamInstEqn GhcPs] } : ty_fam_inst_eqns ';' ty_fam_inst_eqn - {% let (L loc (anns, eqn)) = $3 in - asl (unLoc $1) $2 (L loc eqn) - >> ams (\_ -> $3) anns - >> return (sLL $1 $> (L loc eqn : unLoc $1)) } - | ty_fam_inst_eqns ';' {% addAnnotation (gl $1) AnnSemi (gl $2) - >> return (sLL $1 $> (unLoc $1)) } - | ty_fam_inst_eqn {% let (L loc (anns, eqn)) = $1 in - ams (\_ -> $1) anns - >> return (sLL $1 $> [L loc eqn]) } + {% let (L loc eqn) = $3 in + case unLoc $1 of + [] -> return (sLLlA $1 $> (L loc eqn : unLoc $1)) + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return (sLLlA $1 $> ($3 : h' : t)) } + | ty_fam_inst_eqns ';' {% case unLoc $1 of + [] -> return (sLL $1 $> (unLoc $1)) + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return (sLL $1 $> (h':t)) } + | ty_fam_inst_eqn { sLLAA $1 $> [$1] } | {- empty -} { noLoc [] } -ty_fam_inst_eqn :: { Located ([AddApiAnn],TyFamInstEqn GhcPs) } +ty_fam_inst_eqn :: { LTyFamInstEqn GhcPs } : 'forall' tv_bndrs '.' type '=' ktype {% do { hintExplicitForall $1 - ; (eqn,ann) <- mkTyFamInstEqn (Just $2) $4 $6 - ; return (sLL $1 $> - (mu AnnForall $1:mj AnnDot $3:mj AnnEqual $5:ann,eqn)) } } + ; mkTyFamInstEqn (comb2 $1 $>) (Just $2) $4 $6 (mu AnnForall $1:mj AnnDot $3:mj AnnEqual $5:[]) }} | type '=' ktype - {% do { (eqn,ann) <- mkTyFamInstEqn Nothing $1 $3 - ; return (sLL $1 $> (mj AnnEqual $2:ann, eqn)) } } + -- {% do { (eqn,ann) <- mkTyFamInstEqn Nothing $1 $3 + -- ; return (sLL $1 $> (mj AnnEqual $2:ann, eqn)) } } + {% mkTyFamInstEqn (comb2 $1 $>) Nothing $1 $3 (mj AnnEqual $2:[]) } -- Note the use of type for the head; this allows -- infix type constructors and type patterns @@ -1313,39 +1299,32 @@ ty_fam_inst_eqn :: { Located ([AddApiAnn],TyFamInstEqn GhcPs) } at_decl_cls :: { LHsDecl GhcPs } : -- data family declarations, with optional 'family' keyword 'data' opt_family type opt_datafam_kind_sig - {% amms (liftM mkTyClD (mkFamDecl (comb3 $1 $3 $4) DataFamily $3 + {% liftM mkTyClD (mkFamDecl (comb3 $1 $3 $4) DataFamily $3 (snd $ unLoc $4) Nothing - (ApiAnn (mj AnnData $1:$2++(fst $ unLoc $4)) noCom))) - (mj AnnData $1:$2++(fst $ unLoc $4)) } + (mj AnnData $1:$2++(fst $ unLoc $4))) } -- type family declarations, with optional 'family' keyword -- (can't use opt_instance because you get shift/reduce errors | 'type' type opt_at_kind_inj_sig - {% amms (liftM mkTyClD + {% liftM mkTyClD (mkFamDecl (comb3 $1 $2 $3) OpenTypeFamily $2 (fst . snd $ unLoc $3) (snd . snd $ unLoc $3) - (ApiAnn (mj AnnType $1:(fst $ unLoc $3)) noCom))) - (mj AnnType $1:(fst $ unLoc $3)) } + (mj AnnType $1:(fst $ unLoc $3)) )} | 'type' 'family' type opt_at_kind_inj_sig - {% amms (liftM mkTyClD + {% liftM mkTyClD (mkFamDecl (comb3 $1 $3 $4) OpenTypeFamily $3 (fst . snd $ unLoc $4) (snd . snd $ unLoc $4) - (ApiAnn (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4)) noCom))) - (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4)) } + (mj AnnType $1:mj AnnFamily $2:(fst $ unLoc $4)))} -- default type instances, with optional 'instance' keyword | 'type' ty_fam_inst_eqn - {% ams (\_ -> $2) (fst $ unLoc $2) >> - amms (liftM mkInstD (mkTyFamInst (comb2 $1 $2) (snd $ unLoc $2) - (ApiAnn (mj AnnType $1:(fst $ unLoc $2)) noCom))) - (mj AnnType $1:(fst $ unLoc $2)) } + {% liftM mkInstD (mkTyFamInst (comb2A $1 $2) (unLoc $2) + [mj AnnType $1]) } | 'type' 'instance' ty_fam_inst_eqn - {% ams (\_ -> $3) (fst $ unLoc $3) >> - amms (liftM mkInstD (mkTyFamInst (comb2 $1 $3) (snd $ unLoc $3) - (ApiAnn (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) noCom))) - (mj AnnType $1:mj AnnInstance $2:(fst $ unLoc $3)) } + {% liftM mkInstD (mkTyFamInst (comb2A $1 $3) (unLoc $3) + (mj AnnType $1:mj AnnInstance $2:[]) )} opt_family :: { [AddApiAnn] } : {- empty -} { [] } @@ -1362,27 +1341,23 @@ at_decl_inst :: { LInstDecl GhcPs } : 'type' opt_instance ty_fam_inst_eqn -- Note the use of type for the head; this allows -- infix type constructors and type patterns - {% ams (\_ -> $3) (fst $ unLoc $3) >> - amms (mkTyFamInst (comb2 $1 $3) (snd $ unLoc $3) - (ApiAnn (mj AnnType $1:$2++(fst $ unLoc $3)) noCom)) - (mj AnnType $1:$2++(fst $ unLoc $3)) } + {% mkTyFamInst (comb2A $1 $3) (unLoc $3) + (mj AnnType $1:$2) } -- data/newtype instance declaration, with optional 'instance' keyword | data_or_newtype opt_instance capi_ctype tycl_hdr_inst constrs maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) + {% mkDataFamInst (comb4 $1 $4 $5 $6) (snd $ unLoc $1) $3 (snd $ unLoc $4) Nothing (reverse (snd $ unLoc $5)) (fmap reverse $6) - (ApiAnn ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)) noCom)) - ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)) } + ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)) } -- GADT instance declaration, with optional 'instance' keyword | data_or_newtype opt_instance capi_ctype tycl_hdr_inst opt_kind_sig gadt_constrlist maybe_derivings - {% amms (mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 + {% mkDataFamInst (comb4 $1 $4 $6 $7) (snd $ unLoc $1) $3 (snd $ unLoc $4) (snd $ unLoc $5) (snd $ unLoc $6) (fmap reverse $7) - (ApiAnn ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) noCom)) ((fst $ unLoc $1):$2++(fst $ unLoc $4)++(fst $ unLoc $5)++(fst $ unLoc $6)) } data_or_newtype :: { Located (AddApiAnn, NewOrData) } @@ -1421,36 +1396,32 @@ opt_at_kind_inj_sig :: { Located ([AddApiAnn], ( LFamilyResultSig GhcPs -- T Int [a] -- for associated types -- Rather a lot of inlining here, else we get reduce/reduce errors tycl_hdr :: { Located (Maybe (LHsContext GhcPs), LHsType GhcPs) } - : context '=>' type {% addAnnotation (gl $1) (toUnicodeAnn AnnDarrow $2) (gl $2) - >> (return (sLL $1 $> (Just $1, $3))) - } + : context '=>' type {% do { ctxs <- amsA $1 [mu AnnDarrow $2] + ; return (sLLAl $1 $> (Just ctxs, $3))}} | type { sL1 $1 (Nothing, $1) } tycl_hdr_inst :: { Located ([AddApiAnn],(Maybe (LHsContext GhcPs), Maybe [LHsTyVarBndr GhcPs], LHsType GhcPs)) } - : 'forall' tv_bndrs '.' context '=>' type {% hintExplicitForall $1 - >> (addAnnotation (gl $4) (toUnicodeAnn AnnDarrow $5) (gl $5) - >> return (sLL $1 $> ([mu AnnForall $1, mj AnnDot $3] - , (Just $4, Just $2, $6))) - ) - } + : 'forall' tv_bndrs '.' context '=>' type {% do { hintExplicitForall $1 + ; ctxs <- amsA $4 [mu AnnDarrow $5] + ; return (sLL $1 $> ([mu AnnForall $1, mj AnnDot $3] + , (Just ctxs, Just $2, $6)))}} | 'forall' tv_bndrs '.' type {% hintExplicitForall $1 >> return (sLL $1 $> ([mu AnnForall $1, mj AnnDot $3] , (Nothing, Just $2, $4))) } - | context '=>' type {% addAnnotation (gl $1) (toUnicodeAnn AnnDarrow $2) (gl $2) - >> (return (sLL $1 $>([], (Just $1, Nothing, $3)))) - } + | context '=>' type {% do {ctxs <- amsA $1 [mu AnnDarrow $2] + ; return (sLLAl $1 $>([], (Just ctxs, Nothing, $3)))}} | type { sL1 $1 ([], (Nothing, Nothing, $1)) } -capi_ctype :: { Maybe (Located CType) } +capi_ctype :: { Maybe (LocatedA CType) } capi_ctype : '{-# CTYPE' STRING STRING '#-}' - {% ajs (\_ -> sLL $1 $> (CType (getCTYPEs $1) (Just (Header (getSTRINGs $2) (getSTRING $2))) + {% fmap Just $ amsr (sLL $1 $> (CType (getCTYPEs $1) (Just (Header (getSTRINGs $2) (getSTRING $2))) (getSTRINGs $3,getSTRING $3))) [mo $1,mj AnnHeader $2,mj AnnVal $3,mc $4] } | '{-# CTYPE' STRING '#-}' - {% ajs (\_ -> sLL $1 $> (CType (getCTYPEs $1) Nothing (getSTRINGs $2, getSTRING $2))) + {% fmap Just $ amsr (sLL $1 $> (CType (getCTYPEs $1) Nothing (getSTRINGs $2, getSTRING $2))) [mo $1,mj AnnVal $2,mc $3] } | { Nothing } @@ -1463,9 +1434,10 @@ stand_alone_deriving :: { LDerivDecl GhcPs } : 'deriving' deriv_standalone_strategy 'instance' overlap_pragma inst_type {% do { let { err = text "in the stand-alone deriving instance" <> colon <+> quotes (ppr $5) } - ; ams (\_ -> sLL $1 (hsSigType $>) - (DerivDecl noExtField (mkHsWildCardBndrs $5) $2 $4)) - [mj AnnDeriving $1, mj AnnInstance $3] } } + ; acs (\cs -> sLL $1 (hsSigType $>) + (DerivDecl (ApiAnn [mj AnnDeriving $1, mj AnnInstance $3] cs) (mkHsWildCardBndrs $5) $2 $4)) }} +-- AZ working above + ----------------------------------------------------------------------------- -- Role annotations @@ -1684,24 +1656,30 @@ wherebinds :: { Located ([AddApiAnn],Located (HsLocalBinds GhcPs)) } ----------------------------------------------------------------------------- -- Transformation Rules -rules :: { OrdList (LRuleDecl GhcPs) } - : rules ';' rule {% addAnnotation (oll $1) AnnSemi (gl $2) - >> return ($1 `snocOL` $3) } - | rules ';' {% addAnnotation (oll $1) AnnSemi (gl $2) - >> return $1 } - | rule { unitOL $1 } - | {- empty -} { nilOL } +rules :: { [LRuleDecl GhcPs] } -- Reversed + : rules ';' rule {% case $1 of + [] -> return ($3:$1) + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return ($3:h':t) } + | rules ';' {% case $1 of + [] -> return $1 + (h:t) -> do + h' <- addAnnotationA h AnnSemi (gl $2) + return (h':t) } + | rule { [$1] } + | {- empty -} { [] } rule :: { LRuleDecl GhcPs } : STRING rule_activation rule_foralls infixexp '=' exp {%runECP_P $4 >>= \ $4 -> runECP_P $6 >>= \ $6 -> - ams (\_ -> sLLlA $1 $> $ HsRule { rd_ext = noExtField + acsA (\cs -> sLLlA $1 $> $ HsRule + { rd_ext = ApiAnn (mj AnnEqual $5 : (fst $2) ++ (fstOf3 $3)) cs , rd_name = L (gl $1) (getSTRINGs $1, getSTRING $1) , rd_act = (snd $2) `orElse` AlwaysActive , rd_tyvs = sndOf3 $3, rd_tmvs = thdOf3 $3 - , rd_lhs = reLoc $4, rd_rhs = reLoc $6 }) - (mj AnnEqual $5 : (fst $2) ++ (fstOf3 $3)) } + , rd_lhs = reLoc $4, rd_rhs = reLoc $6 }) } -- Rules can be specified to be NeverActive, unlike inline/specialize pragmas rule_activation :: { ([AddApiAnn],Maybe Activation) } @@ -1844,7 +1822,7 @@ annotation :: { LHsDecl GhcPs } ----------------------------------------------------------------------------- -- Foreign import and export declarations -fdecl :: { Located ([AddApiAnn],HsDecl GhcPs) } +fdecl :: { Located ([AddApiAnn],ApiAnn -> HsDecl GhcPs) } fdecl : 'import' callconv safety fspec {% mkImport $2 $3 (snd $ unLoc $4) >>= \i -> return (sLL $1 $> (mj AnnImport $1 : (fst $ unLoc $4),i)) } @@ -1940,11 +1918,12 @@ ctype :: { LHsType GhcPs } , hst_xforall = ApiAnn [mu AnnForall $1,fv_ann] cs , hst_body = $4 }) [mu AnnForall $1,fv_ann] } - | context '=>' ctype {% addAnnotation (gl $1) (toUnicodeAnn AnnDarrow $2) (gl $2) - >> return (sLL $1 $> $ + | context '=>' ctype {% do { ctxs <- amsA $1 [mu AnnDarrow $2] + ; return (sLLAl $1 $> $ HsQualTy { hst_ctxt = $1 , hst_xqual = ApiAnn [mu AnnDarrow $2] noCom - , hst_body = $3 }) } + , hst_body = $3 })} } + | ipvar '::' type {% ams (\cs -> sLL $1 $> (HsIParamTy (ApiAnn [mu AnnDcolon $2] cs) $1 $3)) [mu AnnDcolon $2] } | type { $1 } @@ -1970,11 +1949,11 @@ ctypedoc :: { LHsType GhcPs } , hst_xforall = ApiAnn [mu AnnForall $1,fv_ann] cs , hst_body = $4 }) [mu AnnForall $1,fv_ann] } - | context '=>' ctypedoc {% addAnnotation (gl $1) (toUnicodeAnn AnnDarrow $2) (gl $2) - >> return (sLL $1 $> $ + | context '=>' ctypedoc {% do { ctxs <- amsA $1 [mu AnnDarrow $2] + ; return (sLLAl $1 $> $ HsQualTy { hst_ctxt = $1 , hst_xqual = ApiAnn [mu AnnDarrow $2] noCom - , hst_body = $3 }) } + , hst_body = $3 }) }} | ipvar '::' type {% ams (\cs -> sLL $1 $> (HsIParamTy (ApiAnn [mu AnnDcolon $2] cs) $1 $3)) [mu AnnDcolon $2] } | typedoc { $1 } @@ -1987,20 +1966,20 @@ ctypedoc :: { LHsType GhcPs } -- looks so much like a tuple type. We can't tell until we find the => context :: { LHsContext GhcPs } - : btype {% do { (anns,ctx) <- checkContext $1 + : btype {% do { ctx <- checkContext $1 ; if null (unLoc ctx) then addAnnotation (gl $1) AnnUnit (gl $1) else return () - ; ams (\_ -> ctx) anns + ; return ctx } } -- See Note [Constr variations of non-terminals] constr_context :: { LHsContext GhcPs } - : constr_btype {% do { (anns,ctx) <- checkContext $1 + : constr_btype {% do { ctx <- checkContext $1 ; if null (unLoc ctx) then addAnnotation (gl $1) AnnUnit (gl $1) else return () - ; ams (\_ -> ctx) anns + ; return ctx } } {- Note [GADT decl discards annotations] @@ -2347,7 +2326,7 @@ They must be kept identical except for their treatment of 'docprev'. constr :: { LConDecl GhcPs } : maybe_docnext forall constr_context '=>' constr_stuff {% ams (\_ -> let (con,details,doc_prev) = unLoc $5 in - addConDoc (L (comb4 $2 $3 $4 $5) (mkConDeclH98 con + addConDoc (L (comb4 $2 (reLoc $3) $4 $5) (mkConDeclH98 con (snd $ unLoc $2) (Just $3) details)) @@ -2401,12 +2380,12 @@ derivings :: { HsDeriving GhcPs } -- know the rightmost extremity of the 'deriving' clause deriving :: { LHsDerivingClause GhcPs } : 'deriving' deriv_clause_types - {% let { full_loc = comb2 $1 $> } + {% let { full_loc = comb2A $1 $> } in ams (\_ -> L full_loc $ HsDerivingClause noExtField Nothing $2) [mj AnnDeriving $1] } | 'deriving' deriv_strategy_no_via deriv_clause_types - {% let { full_loc = comb2 $1 $> } + {% let { full_loc = comb2A $1 $> } in ams (\_ -> L full_loc $ HsDerivingClause noExtField (Just $2) $3) [mj AnnDeriving $1] } @@ -2415,11 +2394,11 @@ deriving :: { LHsDerivingClause GhcPs } in ams (\_ -> L full_loc $ HsDerivingClause noExtField (Just $3) $2) [mj AnnDeriving $1] } -deriv_clause_types :: { Located [LHsSigType GhcPs] } - : qtycondoc { sL1 $1 [mkLHsSigType $1] } - | '(' ')' {% ams (\_ -> sLL $1 $> []) +deriv_clause_types :: { LocatedA [LHsSigType GhcPs] } + : qtycondoc { sL1a $1 [mkLHsSigType $1] } + | '(' ')' {% amsr (sLL $1 $> []) [mop $1,mcp $2] } - | '(' deriv_types ')' {% ams (\_ -> sLL $1 $> $2) + | '(' deriv_types ')' {% amsr (sLL $1 $> $2) [mop $1,mcp $3] } -- Glasgow extension: allow partial -- applications in derivings @@ -4166,6 +4145,9 @@ ams a bs = do cs <- addAnnsAt l bs return (a cs) +acsA :: MonadP m => (ApiAnnComments -> Located a) -> m (LocatedA a) +acsA a = reLocA <$> acs a + acs :: MonadP m => (ApiAnnComments -> Located a) -> m (Located a) acs a = do let (L l _) = a [] @@ -4178,9 +4160,15 @@ acsExpr a = do { expr :: (LHsExpr GhcPs) <- runPV $ acs a amsA :: MonadP m => LocatedA a -> [AddApiAnn] -> m (LocatedA a) -amsA a@(L l _) bs = do +amsA (L l a) bs = do cs <- addAnnsAt (locA l) bs - return a + let aa = addAnns (ann l) bs cs + return (L (SrcSpanAnn aa (locA l)) a) + +reA :: MonadP m => Located a -> LocatedA b -> [AddApiAnn] -> m (LocatedA b) +reA x y@(L la b) bs = do + let l = comb2A x y + amsA (L (SrcSpanAnn (ann la) l) b) bs amsr :: MonadP m => Located a -> [AddApiAnn] -> m (LocatedA a) amsr a@(L l _) bs = do @@ -4194,6 +4182,9 @@ amsL sp bs = addAnnsAt sp bs >> return () ajs :: MonadP m => (ApiAnnComments -> Located a) -> [AddApiAnn] -> m (Maybe (Located a)) ajs a bs = Just <$> ams a bs +acsj :: MonadP m => (ApiAnnComments -> Located a) -> m (Maybe (Located a)) +acsj a = Just <$> acs a + -- |Add a list of AddApiAnns to the given AST element, where the AST element is the -- result of a monadic action amms :: MonadP m => m (Located a) -> [AddApiAnn] -> m (Located a) @@ -4224,6 +4215,12 @@ amsu a bs = do cs <- addAnnsAt l bs return (unitOL (a cs)) +amcsu :: (ApiAnnComments -> Located a) -> P (OrdList (Located a)) +amcsu a = do + let (L l _) = a [] + cs <- addAnnsAt l [] + return (unitOL (a cs)) + -- |Synonyms for AddApiAnn versions of AnnOpen and AnnClose mo,mc :: Located Token -> AddApiAnn mo ll = mj AnnOpen ll @@ -4294,4 +4291,9 @@ allocateCommentsS :: SrcSpan -> P [RealLocated AnnotationComment] allocateCommentsS (RealSrcSpan l _) = allocateCommentsP l allocateCommentsS _ = return [] +addAnnotationA :: MonadP m => LocatedA a -> AnnKeywordId -> SrcSpan -> m (LocatedA a) +addAnnotationA (L la a) kw span = do + cs <- addAnnsAt (locA la) [] + let anns' = addAnns (ann la) [AddApiAnn kw span] cs + return (L (SrcSpanAnn anns' (locA la)) a) } ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -169,17 +169,17 @@ mkClassDecl :: SrcSpan -> Located (Maybe (LHsContext GhcPs), LHsType GhcPs) -> Located (a,[LHsFunDep GhcPs]) -> OrdList (LHsDecl GhcPs) - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls annsIn = do { (binds, sigs, ats, at_defs, _, docs) <- cvBindsAndSigs where_cls - ; let cxt = fromMaybe (noLoc []) mcxt + ; let cxt = fromMaybe (noLocA []) mcxt ; (cls, tparams, fixity, ann) <- checkTyClHdr True tycl_hdr ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan ; (tyvars,annst) <- checkTyVars (text "class") whereDots cls tparams ; cs2 <- addAnnsAt loc annst -- Add any API Annotations to the top SrcSpan - ; let anns' = addAnns annsIn (ann++annst) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann++annst) (cs1 ++ cs2) ; return (L loc (ClassDecl { tcdCExt = anns', tcdCtxt = cxt , tcdLName = cls, tcdTyVars = tyvars , tcdFixity = fixity @@ -191,12 +191,12 @@ mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls annsIn mkTyData :: SrcSpan -> NewOrData - -> Maybe (Located CType) + -> Maybe (LocatedA CType) -> Located (Maybe (LHsContext GhcPs), LHsType GhcPs) -> Maybe (LHsKind GhcPs) -> [LConDecl GhcPs] -> HsDeriving GhcPs - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkTyData loc new_or_data cType (L _ (mcxt, tycl_hdr)) ksig data_cons maybe_deriv annsIn @@ -204,7 +204,7 @@ mkTyData loc new_or_data cType (L _ (mcxt, tycl_hdr)) ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] ; (tyvars, anns) <- checkTyVars (ppr new_or_data) equalsDots tc tparams ; cs2 <- addAnnsAt loc anns -- Add any API Annotations to the top SrcSpan [temp] - ; let anns' = addAnns annsIn (ann ++ anns) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann ++ anns) (cs1 ++ cs2) ; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv ; return (L loc (DataDecl { tcdDExt = anns', tcdLName = tc, tcdTyVars = tyvars, @@ -212,7 +212,7 @@ mkTyData loc new_or_data cType (L _ (mcxt, tycl_hdr)) tcdDataDefn = defn })) } mkDataDefn :: NewOrData - -> Maybe (Located CType) + -> Maybe (LocatedA CType) -> Maybe (LHsContext GhcPs) -> Maybe (LHsKind GhcPs) -> [LConDecl GhcPs] @@ -220,7 +220,7 @@ mkDataDefn :: NewOrData -> P (HsDataDefn GhcPs) mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv = do { checkDatatypeContext mcxt - ; let cxt = fromMaybe (noLoc []) mcxt + ; let cxt = fromMaybe (noLocA []) mcxt ; return (HsDataDefn { dd_ext = noExtField , dd_ND = new_or_data, dd_cType = cType , dd_ctxt = cxt @@ -232,14 +232,14 @@ mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv mkTySynonym :: SrcSpan -> LHsType GhcPs -- LHS -> LHsType GhcPs -- RHS - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkTySynonym loc lhs rhs annsIn = do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] ; (tyvars, anns) <- checkTyVars (text "type") equalsDots tc tparams ; cs2 <- addAnnsAt loc anns -- Add any API Annotations to the top SrcSpan [temp] - ; let anns' = addAnns annsIn (ann ++ anns) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann ++ anns) (cs1 ++ cs2) ; return (L loc (SynDecl { tcdSExt = anns' , tcdLName = tc, tcdTyVars = tyvars , tcdFixity = fixity @@ -249,12 +249,13 @@ mkStandaloneKindSig :: SrcSpan -> Located [LocatedA RdrName] -- LHS -> LHsKind GhcPs -- RHS - -> ApiAnn + -> [AddApiAnn] -> P (LStandaloneKindSig GhcPs) mkStandaloneKindSig loc lhs rhs anns = do { vs <- mapM check_lhs_name (unLoc lhs) ; v <- check_singular_lhs (reverse vs) - ; return $ L loc $ StandaloneKindSig anns v (mkLHsSigType rhs) } + ; cs <- addAnnsAt loc [] + ; return $ L loc $ StandaloneKindSig (ApiAnn anns cs) v (mkLHsSigType rhs) } where check_lhs_name :: LocatedA RdrName -> P (LocatedA RdrName) -- AZ temp check_lhs_name v@(unLoc->name) = @@ -272,39 +273,42 @@ mkStandaloneKindSig loc lhs rhs anns = 2 (pprWithCommas ppr vs) , text "See https://gitlab.haskell.org/ghc/ghc/issues/16754 for details." ] -mkTyFamInstEqn :: Maybe [LHsTyVarBndr GhcPs] +mkTyFamInstEqn :: SrcSpan + -> Maybe [LHsTyVarBndr GhcPs] -> LHsType GhcPs -> LHsType GhcPs - -> P (TyFamInstEqn GhcPs,[AddApiAnn]) -mkTyFamInstEqn bndrs lhs rhs + -> [AddApiAnn] + -> P (LTyFamInstEqn GhcPs) +mkTyFamInstEqn loc bndrs lhs rhs anns = do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs - ; return (mkHsImplicitBndrs - (FamEqn { feqn_ext = noExtField + ; cs <- addAnnsAt loc [] + ; return (L (noAnnSrcSpan loc) $ mkHsImplicitBndrs + (FamEqn { feqn_ext = ApiAnn (anns `mappend` ann) cs , feqn_tycon = tc , feqn_bndrs = bndrs , feqn_pats = tparams , feqn_fixity = fixity - , feqn_rhs = rhs }), - ann) } + , feqn_rhs = rhs })) } mkDataFamInst :: SrcSpan -> NewOrData - -> Maybe (Located CType) + -> Maybe (LocatedA CType) -> (Maybe ( LHsContext GhcPs), Maybe [LHsTyVarBndr GhcPs] , LHsType GhcPs) -> Maybe (LHsKind GhcPs) -> [LConDecl GhcPs] -> HsDeriving GhcPs - -> ApiAnn + -> [AddApiAnn] -> P (LInstDecl GhcPs) mkDataFamInst loc new_or_data cType (mcxt, bndrs, tycl_hdr) ksig data_cons maybe_deriv anns = do { (tc, tparams, fixity, ann) <- checkTyClHdr False tycl_hdr ; -- AZ:TODO: deal with these comments - ; _cs <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] + ; cs <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] + ; let anns' = addAnns (ApiAnn ann cs) anns [] ; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv - ; return (L loc (DataFamInstD anns (DataFamInstDecl (mkHsImplicitBndrs - (FamEqn { feqn_ext = noExtField + ; return (L loc (DataFamInstD anns' (DataFamInstDecl (mkHsImplicitBndrs + (FamEqn { feqn_ext = noAnn -- AZ: get anns , feqn_tycon = tc , feqn_bndrs = bndrs , feqn_pats = tparams @@ -313,24 +317,25 @@ mkDataFamInst loc new_or_data cType (mcxt, bndrs, tycl_hdr) mkTyFamInst :: SrcSpan -> TyFamInstEqn GhcPs - -> ApiAnn + -> [AddApiAnn] -> P (LInstDecl GhcPs) -mkTyFamInst loc eqn anns - = return (L loc (TyFamInstD anns (TyFamInstDecl eqn))) +mkTyFamInst loc eqn anns = do + cs <- addAnnsAt loc [] + return (L loc (TyFamInstD (ApiAnn anns cs) (TyFamInstDecl eqn))) mkFamDecl :: SrcSpan -> FamilyInfo GhcPs -> LHsType GhcPs -- LHS -> Located (FamilyResultSig GhcPs) -- Optional result signature -> Maybe (LInjectivityAnn GhcPs) -- Injectivity annotation - -> ApiAnn + -> [AddApiAnn] -> P (LTyClDecl GhcPs) mkFamDecl loc info lhs ksig injAnn annsIn = do { (tc, tparams, fixity, ann) <- checkTyClHdr False lhs ; cs1 <- addAnnsAt loc ann -- Add any API Annotations to the top SrcSpan [temp] ; (tyvars, anns) <- checkTyVars (ppr info) equals_or_where tc tparams ; cs2 <- addAnnsAt loc anns -- Add any API Annotations to the top SrcSpan [temp] - ; let anns' = addAnns annsIn (ann++anns) (cs1 ++ cs2) + ; let anns' = addAnns (ApiAnn annsIn []) (ann++anns) (cs1 ++ cs2) ; return (L loc (FamDecl anns' (FamilyDecl { fdExt = noExtField , fdInfo = info, fdLName = tc @@ -876,7 +881,7 @@ checkDatatypeContext Nothing = return () checkDatatypeContext (Just c) = do allowed <- getBit DatatypeContextsBit unless allowed $ - addError (getLoc c) + addError (getLocA c) (text "Illegal datatype context (use DatatypeContexts):" <+> pprLHsContext c) @@ -1033,23 +1038,24 @@ checkCmdBlockArguments :: LHsCmd GhcPs -> PV () -- (Eq a) --> [Eq a] -- (((Eq a))) --> [Eq a] -- @ -checkContext :: LHsType GhcPs -> P ([AddApiAnn],LHsContext GhcPs) -checkContext (L l orig_t) - = check [] (L l orig_t) +checkContext :: LHsType GhcPs -> P (LHsContext GhcPs) +checkContext (L l orig_t) = do + cs <- addAnnsAt l [] + check (ApiAnn [] cs) (L l orig_t) where - check anns (L lp (HsTupleTy _ HsBoxedOrConstraintTuple ts)) + check :: ApiAnn -> LHsType GhcPs -> P (LHsContext GhcPs) + check anns (L _l (HsTupleTy ann' HsBoxedOrConstraintTuple ts)) -- (Eq a, Ord b) shows up as a tuple type. Only boxed tuples can -- be used as context constraints. - = return (anns ++ mkParensApiAnn lp,L l ts) -- Ditto () + = return (L (SrcSpanAnn (anns `mappend` ann') l) ts) -- Ditto () - check anns (L lp1 (HsParTy _ ty)) + check anns (L _lp1 (HsParTy ann' ty)) -- to be sure HsParTy doesn't get into the way - = check anns' ty - where anns' = if l == lp1 then anns - else (anns ++ mkParensApiAnn lp1) + = check (anns `mappend` ann') ty -- no need for anns, returning original - check _anns t = checkNoDocs msg t *> return ([],L l [L l orig_t]) + check anns t = checkNoDocs msg t + *> return (L (SrcSpanAnn anns l) [L l orig_t]) msg = text "data constructor context" @@ -2699,7 +2705,7 @@ mkInlinePragma src (inl, match_info) mb_act mkImport :: Located CCallConv -> Located Safety -> (Located StringLiteral, LocatedA RdrName, LHsSigType GhcPs) - -> P (HsDecl GhcPs) + -> P (ApiAnn -> HsDecl GhcPs) mkImport cconv safety (L loc (StringLiteral esrc entity), v, ty) = case unLoc cconv of CCallConv -> mkCImport @@ -2728,8 +2734,8 @@ mkImport cconv safety (L loc (StringLiteral esrc entity), v, ty) = funcTarget = CFunction (StaticTarget esrc entity' Nothing True) importSpec = CImport cconv safety Nothing funcTarget (L loc esrc) - returnSpec spec = return $ ForD noExtField $ ForeignImport - { fd_i_ext = noExtField + returnSpec spec = return $ \ann -> ForD noExtField $ ForeignImport + { fd_i_ext = ann , fd_name = v , fd_sig_ty = ty , fd_fi = spec @@ -2800,10 +2806,10 @@ parseCImport cconv safety nm str sourceText = -- mkExport :: Located CCallConv -> (Located StringLiteral, LocatedA RdrName, LHsSigType GhcPs) - -> P (HsDecl GhcPs) + -> P (ApiAnn -> HsDecl GhcPs) mkExport (L lc cconv) (L le (StringLiteral esrc entity), v, ty) - = return $ ForD noExtField $ - ForeignExport { fd_e_ext = noExtField, fd_name = v, fd_sig_ty = ty + = return $ \ann -> ForD noExtField $ + ForeignExport { fd_e_ext = ann, fd_name = v, fd_sig_ty = ty , fd_fe = CExport (L lc (CExportStatic esrc entity' cconv)) (L le esrc) } where @@ -2888,11 +2894,11 @@ mkTypeImpExp name = text "Illegal keyword 'type' (use ExplicitNamespaces to enable)" return (fmap (`setRdrNameSpace` tcClsName) name) -checkImportSpec :: Located [LIE GhcPs] -> P (Located [LIE GhcPs]) +checkImportSpec :: LocatedA [LIE GhcPs] -> P (LocatedA [LIE GhcPs]) checkImportSpec ie@(L _ specs) = case [l | (L l (IEThingWith _ _ (IEWildcard _) _ _)) <- specs] of [] -> return ie - (l:_) -> importSpecError l + (l:_) -> importSpecError (locA l) where importSpecError l = addFatalError l @@ -2982,7 +2988,7 @@ data PV_Context = data PV_Accum = PV_Accum { pv_messages :: DynFlags -> Messages - , pv_annotations :: [(ApiAnnKey,[RealSrcSpan])] + -- AZ , pv_annotations :: [(ApiAnnKey,[RealSrcSpan])] , pv_comment_q :: [RealLocated AnnotationComment] , pv_annotations_comments :: [(RealSrcSpan,[RealLocated AnnotationComment])] } @@ -3017,12 +3023,12 @@ runPV_msg msg m = , pv_hint = msg } pv_acc = PV_Accum { pv_messages = messages s - , pv_annotations = annotations s + -- , pv_annotations = annotations s , pv_comment_q = comment_q s , pv_annotations_comments = annotations_comments s } mkPState acc' = s { messages = pv_messages acc' - , annotations = pv_annotations acc' + -- AZ , annotations = pv_annotations acc' , comment_q = pv_comment_q acc' , annotations_comments = pv_annotations_comments acc' } in @@ -3054,10 +3060,12 @@ instance MonadP PV where let (comment_q', new_ann_comments) = allocateComments l (pv_comment_q acc) annotations_comments' = new_ann_comments ++ pv_annotations_comments acc - annotations' = ((l,a), [v]) : pv_annotations acc + -- annotations' = ((l,a), [v]) : pv_annotations acc acc' = acc - { pv_annotations = annotations' - , pv_comment_q = comment_q' + { + -- AZ pv_annotations = annotations' + -- , + pv_comment_q = comment_q' , pv_annotations_comments = annotations_comments' } in PV_Ok acc' () ===================================== compiler/typecheck/TcBackpack.hs ===================================== @@ -166,7 +166,7 @@ checkHsigIface tcg_env gr sig_iface -- TODO: maybe we can be a little more -- precise here and use the Located -- info for the *specific* name we matched. - -> getLoc e + -> getLocA e _ -> nameSrcSpan name addErrAt loc (badReexportedBootThing False name name') @@ -575,7 +575,7 @@ mergeSignatures -- a signature package (i.e., does not expose any -- modules.) If so, we can thin it. | isFromSignaturePackage - -> setSrcSpan loc $ do + -> setSrcSpan (locA loc) $ do -- Suppress missing errors; they might be used to refer -- to entities from other signatures we are merging in. -- If an identifier truly doesn't exist in any of the @@ -629,7 +629,7 @@ mergeSignatures is_mod = mod_name, is_as = mod_name, is_qual = False, - is_dloc = loc + is_dloc = locA loc } ImpAll rdr_env = mkGlobalRdrEnv (gresFromAvails (Just ispec) as1) setGblEnv tcg_env { ===================================== compiler/typecheck/TcHsSyn.hs ===================================== @@ -1493,7 +1493,7 @@ zonkForeignExport _ for_imp = return for_imp -- Foreign imports don't need zonking zonkRules :: ZonkEnv -> [LRuleDecl GhcTcId] -> TcM [LRuleDecl GhcTc] -zonkRules env rs = mapM (wrapLocM (zonkRule env)) rs +zonkRules env rs = mapM (wrapLocMA (zonkRule env)) rs zonkRule :: ZonkEnv -> RuleDecl GhcTcId -> TcM (RuleDecl GhcTc) zonkRule env rule@(HsRule { rd_tmvs = tm_bndrs{-::[RuleBndr TcId]-} ===================================== compiler/typecheck/TcInstDcls.hs ===================================== @@ -572,7 +572,7 @@ tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn })) -- (1) do the work of verifying the synonym group ; co_ax_branch <- tcTyFamInstEqn fam_tc mb_clsinfo - (L (locA $ getLoc fam_lname) eqn) + (L (getLoc fam_lname) eqn) -- (2) check for validity ===================================== compiler/typecheck/TcRnDriver.hs ===================================== @@ -207,7 +207,7 @@ tcRnModuleTcRnM :: HscEnv tcRnModuleTcRnM hsc_env mod_sum (HsParsedModule { hpm_module = - (L loc (HsModule maybe_mod export_ies + (L loc (HsModule _anns maybe_mod export_ies import_decls local_decls mod_deprec maybe_doc_hdr)), hpm_src_files = src_files @@ -244,9 +244,9 @@ tcRnModuleTcRnM hsc_env mod_sum $ implicitRequirements hsc_env (map simplifyImport (prel_imports ++ import_decls)) - ; let { mkImport (Nothing, L _ mod_name) = noLoc + ; let { mkImport (Nothing, L _ mod_name) = noLocA $ (simpleImportDecl mod_name) - { ideclHiding = Just (False, noLoc [])} + { ideclHiding = Just (False, noLocA [])} ; mkImport _ = panic "mkImport" } ; let { all_imports = prel_imports ++ import_decls ++ map mkImport (raw_sig_imports ++ raw_req_imports) } @@ -396,7 +396,7 @@ tcRnImports hsc_env import_decls tcRnSrcDecls :: Bool -- False => no 'module M(..) where' header at all -> [LHsDecl GhcPs] -- Declarations - -> Maybe (Located [LIE GhcPs]) + -> Maybe (LocatedA [LIE GhcPs]) -> TcM TcGblEnv tcRnSrcDecls explicit_mod_hdr decls export_ies = do { -- Do all the declarations @@ -1716,7 +1716,7 @@ tcTyClsInstDecls tycl_decls deriv_decls binds -} checkMain :: Bool -- False => no 'module M(..) where' header at all - -> Maybe (Located [LIE GhcPs]) -- Export specs of Main module + -> Maybe (LocatedA [LIE GhcPs]) -- Export specs of Main module -> TcM TcGblEnv -- If we are in module Main, check that 'main' is defined and exported. checkMain explicit_mod_hdr export_ies @@ -1724,7 +1724,7 @@ checkMain explicit_mod_hdr export_ies ; tcg_env <- getGblEnv ; check_main dflags tcg_env explicit_mod_hdr export_ies } -check_main :: DynFlags -> TcGblEnv -> Bool -> Maybe (Located [LIE GhcPs]) +check_main :: DynFlags -> TcGblEnv -> Bool -> Maybe (LocatedA [LIE GhcPs]) -> TcM TcGblEnv check_main dflags tcg_env explicit_mod_hdr export_ies | mod /= main_mod @@ -1834,7 +1834,7 @@ check_main dflags tcg_env explicit_mod_hdr export_ies -- Select the main functions from the export list. -- Only the module name is needed, the function name is fixed. - selExportMains :: Maybe (Located [LIE GhcPs]) -> [ModuleName] -- #16453 + selExportMains :: Maybe (LocatedA [LIE GhcPs]) -> [ModuleName] -- #16453 selExportMains Nothing = [main_mod_nm] -- no main specified, but there is a header. selExportMains (Just exps) = fmap fst $ ===================================== compiler/typecheck/TcRnExports.hs ===================================== @@ -152,7 +152,7 @@ type ExportOccMap = OccEnv (Name, IE GhcPs) -- that have the same occurrence name tcRnExports :: Bool -- False => no 'module M(..) where' header at all - -> Maybe (Located [LIE GhcPs]) -- Nothing => no explicit export list + -> Maybe (LocatedA [LIE GhcPs]) -- Nothing => no explicit export list -> TcGblEnv -> RnM TcGblEnv @@ -184,7 +184,7 @@ tcRnExports explicit_mod exports ; let real_exports | explicit_mod = exports | has_main - = Just (noLoc [noLoc (IEVar noAnn + = Just (noLocA [noLocA (IEVar noAnn (noLoc (IEName $ noLocA default_main)))]) -- ToDo: the 'noLoc' here is unhelpful if 'main' -- turns out to be out of scope @@ -212,7 +212,7 @@ tcRnExports explicit_mod exports ; failIfErrsM ; return new_tcg_env } -exports_from_avail :: Maybe (Located [LIE GhcPs]) +exports_from_avail :: Maybe (LocatedA [LIE GhcPs]) -- ^ 'Nothing' means no explicit export list -> GlobalRdrEnv -> ImportAvails @@ -262,7 +262,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod where do_litem :: ExportAccum -> LIE GhcPs -> RnM (Maybe (ExportAccum, (LIE GhcRn, Avails))) - do_litem acc lie = setSrcSpan (getLoc lie) (exports_from_item acc lie) + do_litem acc lie = setSrcSpan (getLocA lie) (exports_from_item acc lie) -- Maps a parent to its in-scope children kids_env :: NameEnv [GlobalRdrElt] ===================================== compiler/typecheck/TcRnMonad.hs ===================================== @@ -60,7 +60,7 @@ module TcRnMonad( -- * Error management getSrcSpanM, setSrcSpan, addLocM, addLocMA, - wrapLocM, wrapLocFstM, wrapLocSndM,wrapLocM_,wrapLocMA, + wrapLocM, wrapLocFstM, wrapLocFstMA, wrapLocSndM,wrapLocM_,wrapLocMA, getErrsVar, setErrsVar, addErr, failWith, failAt, @@ -851,6 +851,12 @@ wrapLocFstM fn (L loc a) = (b,c) <- fn a return (L loc b, c) +wrapLocFstMA :: (a -> TcM (b,c)) -> LocatedA a -> TcM (LocatedA b, c) +wrapLocFstMA fn (L loc a) = + setSrcSpan (locA loc) $ do + (b,c) <- fn a + return (L loc b, c) + wrapLocSndM :: (a -> TcM (b, c)) -> Located a -> TcM (b, Located c) wrapLocSndM fn (L loc a) = setSrcSpan loc $ do ===================================== compiler/typecheck/TcRnTypes.hs ===================================== @@ -509,7 +509,7 @@ data TcGblEnv -- The binds, rules and foreign-decl fields are collected -- initially in un-zonked form and are finally zonked in tcRnSrcDecls - tcg_rn_exports :: Maybe [(Located (IE GhcRn), Avails)], + tcg_rn_exports :: Maybe [(LIE GhcRn, Avails)], -- Nothing <=> no explicit export list -- Is always Nothing if we don't want to retain renamed -- exports. ===================================== compiler/typecheck/TcRules.hs ===================================== @@ -105,7 +105,7 @@ tcRules decls = mapM (wrapLocM tcRuleDecls) decls tcRuleDecls :: RuleDecls GhcRn -> TcM (RuleDecls GhcTcId) tcRuleDecls (HsRules { rds_src = src , rds_rules = decls }) - = do { tc_decls <- mapM (wrapLocM tcRule) decls + = do { tc_decls <- mapM (wrapLocMA tcRule) decls ; return $ HsRules { rds_ext = noExtField , rds_src = src , rds_rules = tc_decls } } ===================================== compiler/typecheck/TcTyClsDecls.hs ===================================== @@ -2620,7 +2620,7 @@ tcInjectivity _ Nothing -- therefore we can always infer the result kind if we know the result type. -- But this does not seem to be useful in any way so we don't do it. (Another -- reason is that the implementation would not be straightforward.) -tcInjectivity tcbs (Just (L loc (InjectivityAnn _ lInjNames))) +tcInjectivity tcbs (Just (L loc (InjectivityAnn _ _ lInjNames))) = setSrcSpan loc $ do { let tvs = binderVars tcbs ; dflags <- getDynFlags @@ -2751,7 +2751,7 @@ kcTyFamInstEqn tc_fam_tc , feqn_bndrs = mb_expl_bndrs , feqn_pats = hs_pats , feqn_rhs = hs_rhs_ty }})) - = setSrcSpan loc $ + = setSrcSpan (locA loc) $ do { traceTc "kcTyFamInstEqn" (vcat [ text "tc_name =" <+> ppr eqn_tc_name , text "fam_tc =" <+> ppr tc_fam_tc <+> dcolon <+> ppr (tyConKind tc_fam_tc) @@ -2793,7 +2793,7 @@ tcTyFamInstEqn fam_tc mb_clsinfo , feqn_pats = hs_pats , feqn_rhs = hs_rhs_ty }})) = ASSERT( getName fam_tc == eqn_tc_name ) - setSrcSpan loc $ + setSrcSpan (locA loc) $ do { traceTc "tcTyFamInstEqn" $ vcat [ ppr fam_tc <+> ppr hs_pats , text "fam tc bndrs" <+> pprTyVars (tyConTyVars fam_tc) @@ -2815,7 +2815,7 @@ tcTyFamInstEqn fam_tc mb_clsinfo -- (tcFamInstEqnGuts zonks to Type) ; return (mkCoAxBranch qtvs [] [] fam_tc pats rhs_ty (map (const Nominal) qtvs) - loc) } + (locA loc)) } tcTyFamInstEqn _ _ _ = panic "tcTyFamInstEqn" ===================================== compiler/utils/OrdList.hs ===================================== @@ -16,6 +16,7 @@ module OrdList ( OrdList, nilOL, isNilOL, unitOL, appOL, consOL, snocOL, concatOL, lastOL, headOL, + initOL, tailOL, unsnocOL, unconsOL, mapOL, fromOL, toOL, foldrOL, foldlOL, reverseOL, fromOLReverse, strictlyEqOL, strictlyOrdOL ) where @@ -73,6 +74,10 @@ concatOL :: [OrdList a] -> OrdList a headOL :: OrdList a -> a lastOL :: OrdList a -> a lengthOL :: OrdList a -> Int +initOL :: OrdList a -> OrdList a +tailOL :: OrdList a -> OrdList a +unsnocOL :: OrdList a -> (OrdList a, a) +unconsOL :: OrdList a -> (a, OrdList a) nilOL = None unitOL as = One as @@ -94,6 +99,36 @@ lastOL (Cons _ as) = lastOL as lastOL (Snoc _ a) = a lastOL (Two _ as) = lastOL as +initOL None = panic "initOL" +initOL (One _) = None +initOL (Many [_]) = None +initOL (Many as) = Many (init as) +initOL (Cons a (Many [_])) = One a +initOL (Cons a (One _)) = One a +initOL (Cons a as) = Cons a (initOL as) +initOL (Snoc as _) = as +initOL (Two as (Many [_])) = as +initOL (Two as (One _)) = as +initOL (Two as bs) = Two as (initOL bs) + +tailOL None = panic "initOL" +tailOL (One _) = None +tailOL (Many [_]) = None +tailOL (Many as) = Many (tail as) +tailOL (Cons _ as) = as +tailOL (Snoc (Many [_]) b) = One b +tailOL (Snoc (One _) b) = One b +tailOL (Snoc as b) = Snoc (tailOL as) b +tailOL (Two (Many [_]) bs) = bs +tailOL (Two (One _) bs) = bs +tailOL (Two as bs) = Two (tailOL as) bs + +unconsOL None = panic "unconsOL" +unconsOL as = (headOL as, tailOL as) + +unsnocOL None = panic "unsnocOL" +unsnocOL as = (initOL as, lastOL as) + lengthOL None = 0 lengthOL (One _) = 1 lengthOL (Many as) = length as View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e8277c02e329408fdb2ad23fd55568630638306d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e8277c02e329408fdb2ad23fd55568630638306d You're receiving 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 2 23:23:09 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 02 Apr 2020 19:23:09 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/caf-cleanups Message-ID: <5e8673dd2ef6e_6167134ebbc4264642@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/caf-cleanups at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/caf-cleanups You're receiving 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 3 02:54:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 02 Apr 2020 22:54:50 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e86a57a2b524_6167134ebbc426695fd@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 17c55f6d by Zubin Duggal at 2020-04-02T22:54:30-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 68d27776 by Andreas Klebinger at 2020-04-02T22:54:30-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - ebaab755 by Moritz Bruder at 2020-04-02T22:54:32-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - e92b296a by Sylvain Henry at 2020-04-02T22:54:37-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - 5fde172a by Sylvain Henry at 2020-04-02T22:54:37-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - 71361023 by Sylvain Henry at 2020-04-02T22:54:37-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 1b6ea036 by Maxim Koltsov at 2020-04-02T22:54:38-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - f6737ff8 by Andreas Klebinger at 2020-04-02T22:54:39-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 7470086a by Simon Peyton Jones at 2020-04-02T22:54:39-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Iface/Ext/Debug.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0465a64d798cc8913325f571445a3d7504f2d92e...7470086a0c6617f020897ca1215a98561fabcf73 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0465a64d798cc8913325f571445a3d7504f2d92e...7470086a0c6617f020897ca1215a98561fabcf73 You're receiving 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 3 04:23:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 03 Apr 2020 00:23:32 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e86ba44a3c69_616776d1c742683951@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: 3965e0b8 by Ben Gamari at 2020-04-03T00:21:12-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Metric Decrease: T12234 T13035 T13719 T14683 T4801 T5631 T9020 T9961 Metric Increase: T14697 T15426 T1969 T5837 T9203 T9872a T9872b T9872c T9872d - - - - - 9 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1001,10 +1001,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1023,6 +1019,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1306,8 +1318,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1552,14 +1563,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1568,8 +1574,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3021,8 +3019,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,73 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3965e0b87c1c9abcc20b2b389300f8a3455aa68e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3965e0b87c1c9abcc20b2b389300f8a3455aa68e You're receiving 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 3 08:51:47 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 03 Apr 2020 04:51:47 -0400 Subject: [Git][ghc/ghc][wip/andreask/strict_dicts] 382 commits: testsuite: Widen acceptance window of T1969 Message-ID: <5e86f9239a46c_61673f81ef22dee42693029@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/andreask/strict_dicts at Glasgow Haskell Compiler / GHC Commits: 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 0e0eb2c3 by Andreas Klebinger at 2020-04-03T10:37:58+02:00 Enable strict dicts by default. For now accept to see what hackage head will say. ------------------------- Metric Decrease: T12227 WWRec T12234 Metric Increase: T9630 T15164 T13056 ------------------------- - - - - - 9bb5aea9 by Andreas Klebinger at 2020-04-03T10:47:23+02:00 Apply SPJ's suggestions - - - - - 551fbc81 by Sebastian Graf at 2020-04-03T10:51:23+02:00 Remove dead code - - - - - 14 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/win32-init.sh - HACKING.md - aclocal.m4 - boot - + compiler/GHC.hs - + compiler/GHC/ByteCode/Asm.hs - + compiler/GHC/ByteCode/InfoTable.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4c3a007a5826bbfcd9594666811869f7343004d...551fbc810471ac54e626c591aaee90e3746311a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4c3a007a5826bbfcd9594666811869f7343004d...551fbc810471ac54e626c591aaee90e3746311a4 You're receiving 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 3 10:25:06 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:25:06 -0400 Subject: [Git][ghc/ghc][master] Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e870f0283c51_61673f81ef22dee427115b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 6 changed files: - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - docs/users_guide/debugging.rst Changes: ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -79,6 +79,7 @@ data DumpFlag | Opt_D_dump_cpr_signatures | Opt_D_dump_tc | Opt_D_dump_tc_ast + | Opt_D_dump_hie | Opt_D_dump_types | Opt_D_dump_rules | Opt_D_dump_cse ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -425,14 +425,14 @@ extract_renamed_stuff mod_summary tc_result = do 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 $ dumpIfSet_dyn dflags Opt_D_dump_hie "HIE AST" FormatHaskell (ppr $ hie_asts hieFile) -- Validate HIE files when (gopt Opt_ValidateHie dflags) $ do hs_env <- Hsc $ \e w -> return (e, w) liftIO $ do -- Validate Scopes - let mdl = hie_module hieFile - case validateScopes mdl $ getAsts $ hie_asts hieFile of + case validateScopes (hie_module hieFile) $ getAsts $ hie_asts hieFile of [] -> putMsg dflags $ text "Got valid scopes" xs -> do putMsg dflags $ text "Got invalid scopes" @@ -445,7 +445,7 @@ extract_renamed_stuff mod_summary tc_result = do putMsg dflags $ text "Got no roundtrip errors" xs -> do putMsg dflags $ text "Got roundtrip errors" - mapM_ (putMsg dflags) xs + mapM_ (putMsg (dopt_set dflags Opt_D_ppr_debug)) xs return rn_info ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2741,6 +2741,8 @@ dynamic_flags_deps = [ (setDumpFlag Opt_D_dump_tc) , make_ord_flag defGhcFlag "ddump-tc-ast" (setDumpFlag Opt_D_dump_tc_ast) + , make_ord_flag defGhcFlag "ddump-hie" + (setDumpFlag Opt_D_dump_hie) , make_ord_flag defGhcFlag "ddump-types" (setDumpFlag Opt_D_dump_types) , make_ord_flag defGhcFlag "ddump-rules" ===================================== compiler/GHC/Iface/Ext/Debug.hs ===================================== @@ -23,35 +23,6 @@ import qualified Data.Map as M import qualified Data.Set as S import Data.Function ( on ) import Data.List ( sortOn ) -import Data.Foldable ( toList ) - -ppHies :: Outputable a => (HieASTs a) -> SDoc -ppHies (HieASTs asts) = M.foldrWithKey go "" asts - where - go k a rest = vcat $ - [ "File: " <> ppr k - , ppHie a - , rest - ] - -ppHie :: Outputable a => HieAST a -> SDoc -ppHie = go 0 - where - go n (Node inf sp children) = hang header n rest - where - rest = vcat $ map (go (n+2)) children - header = hsep - [ "Node" - , ppr sp - , ppInfo inf - ] - -ppInfo :: Outputable a => NodeInfo a -> SDoc -ppInfo ni = hsep - [ ppr $ toList $ nodeAnnotations ni - , ppr $ nodeType ni - , ppr $ M.toList $ nodeIdentifiers ni - ] type Diff a = a -> a -> [SDoc] ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -5,9 +5,11 @@ For more information see https://gitlab.haskell.org/ghc/ghc/wikis/hie-files -} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE OverloadedStrings #-} module GHC.Iface.Ext.Types where import GhcPrelude @@ -21,6 +23,7 @@ import GHC.Types.Name ( Name ) import Outputable hiding ( (<>) ) import GHC.Types.SrcLoc ( RealSrcSpan ) import GHC.Types.Avail +import qualified Outputable as O ( (<>) ) import qualified Data.Array as A import qualified Data.Map as M @@ -210,6 +213,15 @@ instance Binary (HieASTs TypeIndex) where put_ bh asts = put_ bh $ M.toAscList $ getAsts asts get bh = HieASTs <$> fmap M.fromDistinctAscList (get bh) +instance Outputable a => Outputable (HieASTs a) where + ppr (HieASTs asts) = M.foldrWithKey go "" asts + where + go k a rest = vcat $ + [ "File: " O.<> ppr k + , ppr a + , rest + ] + data HieAST a = Node @@ -229,6 +241,11 @@ instance Binary (HieAST TypeIndex) where <*> get bh <*> get bh +instance Outputable a => Outputable (HieAST a) where + ppr (Node ni sp ch) = hang header 2 rest + where + header = text "Node@" O.<> ppr sp O.<> ":" <+> ppr ni + rest = vcat (map ppr ch) -- | The information stored in one AST node. -- @@ -255,6 +272,22 @@ instance Binary (NodeInfo TypeIndex) where <*> get bh <*> fmap (M.fromList) (get bh) +instance Outputable a => Outputable (NodeInfo a) where + ppr (NodeInfo anns typs idents) = braces $ fsep $ punctuate ", " + [ parens (text "annotations:" <+> ppr anns) + , parens (text "types:" <+> ppr typs) + , parens (text "identifier info:" <+> pprNodeIdents idents) + ] + +pprNodeIdents :: Outputable a => NodeIdentifiers a -> SDoc +pprNodeIdents ni = braces $ fsep $ punctuate ", " $ map go $ M.toList ni + where + go (i,id) = parens $ hsep $ punctuate ", " [pprIdentifier i, ppr id] + +pprIdentifier :: Identifier -> SDoc +pprIdentifier (Left mod) = text "module" <+> ppr mod +pprIdentifier (Right name) = text "name" <+> ppr name + type Identifier = Either ModuleName Name type NodeIdentifiers a = M.Map Identifier (IdentifierDetails a) @@ -269,7 +302,7 @@ data IdentifierDetails a = IdentifierDetails } deriving (Eq, Functor, Foldable, Traversable) instance Outputable a => Outputable (IdentifierDetails a) where - ppr x = text "IdentifierDetails" <+> ppr (identType x) <+> ppr (identInfo x) + ppr x = text "Details: " <+> ppr (identType x) <+> ppr (identInfo x) instance Semigroup (IdentifierDetails a) where d1 <> d2 = IdentifierDetails (identType d1 <|> identType d2) @@ -284,7 +317,7 @@ instance Binary (IdentifierDetails TypeIndex) where put_ bh $ S.toAscList $ identInfo dets get bh = IdentifierDetails <$> get bh - <*> fmap (S.fromDistinctAscList) (get bh) + <*> fmap S.fromDistinctAscList (get bh) -- | Different contexts under which identifiers exist @@ -330,10 +363,32 @@ data ContextInfo -- | Record field | RecField RecFieldContext (Maybe Span) - deriving (Eq, Ord, Show) + deriving (Eq, Ord) instance Outputable ContextInfo where - ppr = text . show + ppr (Use) = text "usage" + ppr (MatchBind) = text "LHS of a match group" + ppr (IEThing x) = ppr x + ppr (TyDecl) = text "bound in a type signature declaration" + ppr (ValBind t sc sp) = + ppr t <+> text "value bound with scope:" <+> ppr sc <+> pprBindSpan sp + ppr (PatternBind sc1 sc2 sp) = + text "bound in a pattern with scope:" + <+> ppr sc1 <+> "," <+> ppr sc2 + <+> pprBindSpan sp + ppr (ClassTyDecl sp) = + text "bound in a class type declaration" <+> pprBindSpan sp + ppr (Decl d sp) = + text "declaration of" <+> ppr d <+> pprBindSpan sp + ppr (TyVarBind sc1 sc2) = + text "type variable binding with scope:" + <+> ppr sc1 <+> "," <+> ppr sc2 + ppr (RecField ctx sp) = + text "record field" <+> ppr ctx <+> pprBindSpan sp + +pprBindSpan :: Maybe Span -> SDoc +pprBindSpan Nothing = text "" +pprBindSpan (Just sp) = text "at:" <+> ppr sp instance Binary ContextInfo where put_ bh Use = putByte bh 0 @@ -383,14 +438,19 @@ instance Binary ContextInfo where 9 -> return MatchBind _ -> panic "Binary ContextInfo: invalid tag" - -- | Types of imports and exports data IEType = Import | ImportAs | ImportHiding | Export - deriving (Eq, Enum, Ord, Show) + deriving (Eq, Enum, Ord) + +instance Outputable IEType where + ppr Import = text "import" + ppr ImportAs = text "import as" + ppr ImportHiding = text "import hiding" + ppr Export = text "export" instance Binary IEType where put_ bh b = putByte bh (fromIntegral (fromEnum b)) @@ -402,7 +462,13 @@ data RecFieldContext | RecFieldAssign | RecFieldMatch | RecFieldOcc - deriving (Eq, Enum, Ord, Show) + deriving (Eq, Enum, Ord) + +instance Outputable RecFieldContext where + ppr RecFieldDecl = text "declaration" + ppr RecFieldAssign = text "assignment" + ppr RecFieldMatch = text "pattern match" + ppr RecFieldOcc = text "occurence" instance Binary RecFieldContext where put_ bh b = putByte bh (fromIntegral (fromEnum b)) @@ -412,13 +478,16 @@ instance Binary RecFieldContext where data BindType = RegularBind | InstanceBind - deriving (Eq, Ord, Show, Enum) + deriving (Eq, Ord, Enum) + +instance Outputable BindType where + ppr RegularBind = "regular" + ppr InstanceBind = "instance" instance Binary BindType where put_ bh b = putByte bh (fromIntegral (fromEnum b)) get bh = do x <- getByte bh; pure $! (toEnum (fromIntegral x)) - data DeclType = FamDec -- ^ type or data family | SynDec -- ^ type synonym @@ -427,18 +496,26 @@ data DeclType | PatSynDec -- ^ pattern synonym | ClassDec -- ^ class declaration | InstDec -- ^ instance declaration - deriving (Eq, Ord, Show, Enum) + deriving (Eq, Ord, Enum) + +instance Outputable DeclType where + ppr FamDec = text "type or data family" + ppr SynDec = text "type synonym" + ppr DataDec = text "data" + ppr ConDec = text "constructor" + ppr PatSynDec = text "pattern synonym" + ppr ClassDec = text "class" + ppr InstDec = text "instance" instance Binary DeclType where put_ bh b = putByte bh (fromIntegral (fromEnum b)) get bh = do x <- getByte bh; pure $! (toEnum (fromIntegral x)) - data Scope = NoScope | LocalScope Span | ModuleScope - deriving (Eq, Ord, Show, Typeable, Data) + deriving (Eq, Ord, Typeable, Data) instance Outputable Scope where ppr NoScope = text "NoScope" @@ -488,9 +565,12 @@ data TyVarScope -- method type signature deriving (Eq, Ord) -instance Show TyVarScope where - show (ResolvedScopes sc) = show sc - show _ = error "UnresolvedScope" +instance Outputable TyVarScope where + ppr (ResolvedScopes xs) = + text "type variable scopes:" <+> hsep (punctuate ", " $ map ppr xs) + ppr (UnresolvedScope ns sp) = + text "unresolved type variable scope for name" O.<> plural ns + <+> pprBindSpan sp instance Binary TyVarScope where put_ bh (ResolvedScopes xs) = do ===================================== docs/users_guide/debugging.rst ===================================== @@ -177,6 +177,12 @@ These flags dump various information from GHC's typechecker and renamer. Dump typechecker output as a syntax tree +.. ghc-flag:: -ddump-hie + :shortdesc: Dump the hie file syntax tree + :type: dynamic + + Dump the hie file syntax tree if we are generating extended interface files + .. ghc-flag:: -ddump-splices :shortdesc: Dump TH spliced expressions, and what they evaluate to :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef7576c40f8de391ed8b1c81c38156202e6d17cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef7576c40f8de391ed8b1c81c38156202e6d17cf You're receiving 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 3 10:25:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:25:43 -0400 Subject: [Git][ghc/ghc][master] Improve and refactor StgToCmm codegen for DataCons. Message-ID: <5e870f27b0ed9_61673f81ef22dee42714818@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - 3 changed files: - compiler/GHC/StgToCmm/DataCon.hs - rts/StgMiscClosures.cmm - testsuite/tests/codeGen/should_compile/T15155l.hs Changes: ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -1,4 +1,6 @@ {-# LANGUAGE CPP #-} +{-# OPTIONS -O -ddump-to-file -dumpdir datacondumps -ddump-simpl -ddump-stg #-} +-- {-# OPTIONS -dsuppress-all #-} ----------------------------------------------------------------------------- -- @@ -40,6 +42,8 @@ import GHC.Core.DataCon import GHC.Driver.Session import FastString import GHC.Types.Id +import GHC.Types.Id.Info( CafInfo( NoCafRefs ) ) +import GHC.Types.Name (isInternalName) import GHC.Types.RepType (countConRepArgs) import GHC.Types.Literal import PrelInfo @@ -51,8 +55,6 @@ import MonadUtils (mapMaybeM) import Control.Monad import Data.Char - - --------------------------------------------------------------- -- Top-level constructors --------------------------------------------------------------- @@ -62,10 +64,24 @@ cgTopRhsCon :: DynFlags -> DataCon -- Id -> [NonVoid StgArg] -- Args -> (CgIdInfo, FCode ()) -cgTopRhsCon dflags id con args = - let id_info = litIdInfo dflags id (mkConLFInfo con) (CmmLabel closure_label) - in (id_info, gen_code) +cgTopRhsCon dflags id con args + | Just static_info <- precomputedStaticConInfo_maybe dflags id con args + , let static_code | isInternalName name = pure () + | otherwise = gen_code + = -- There is a pre-allocated static closure available; use it + -- See Note [Precomputed static closures]. + -- For External bindings we must keep the binding, + -- since importing modules will refer to it by name; + -- but for Internal ones we can drop it altogether + -- See Note [About the NameSorts] in Name.hs for Internal/External + (static_info, static_code) + + -- Otherwise generate a closure for the constructor. + | otherwise + = (id_Info, gen_code) + where + id_Info = litIdInfo dflags id (mkConLFInfo con) (CmmLabel closure_label) name = idName id caffy = idCafInfo id -- any stgArgHasCafRefs args closure_label = mkClosureLabel name caffy @@ -124,11 +140,10 @@ buildDynCon :: Id -- Name of the thing to which this constr will -- Return details about how to find it and initialization code buildDynCon binder actually_bound cc con args = do dflags <- getDynFlags - buildDynCon' dflags (targetPlatform dflags) binder actually_bound cc con args + buildDynCon' dflags binder actually_bound cc con args buildDynCon' :: DynFlags - -> Platform -> Id -> Bool -> CostCentreStack -> DataCon @@ -146,78 +161,13 @@ the addr modes of the args is that we may be in a "knot", and premature looking at the args will cause the compiler to black-hole! -} - --------- buildDynCon': Nullary constructors -------------- --- First we deal with the case of zero-arity constructors. They --- will probably be unfolded, so we don't expect to see this case much, --- if at all, but it does no harm, and sets the scene for characters. --- --- In the case of zero-arity constructors, or, more accurately, those --- which have exclusively size-zero (VoidRep) args, we generate no code --- at all. - -buildDynCon' dflags _ binder _ _cc con [] - | isNullaryRepDataCon con - = return (litIdInfo dflags binder (mkConLFInfo con) - (CmmLabel (mkClosureLabel (dataConName con) (idCafInfo binder))), - return mkNop) - --------- buildDynCon': Charlike and Intlike constructors ----------- -{- The following three paragraphs about @Char at -like and @Int at -like -closures are obsolete, but I don't understand the details well enough -to properly word them, sorry. I've changed the treatment of @Char at s to -be analogous to @Int at s: only a subset is preallocated, because @Char@ -has now 31 bits. Only literals are handled here. -- Qrczak - -Now for @Char at -like closures. We generate an assignment of the -address of the closure to a temporary. It would be possible simply to -generate no code, and record the addressing mode in the environment, -but we'd have to be careful if the argument wasn't a constant --- so -for simplicity we just always assign to a temporary. - -Last special case: @Int at -like closures. We only special-case the -situation in which the argument is a literal in the range - at mIN_INTLIKE@.. at mAX_INTLILKE@. NB: for @Char at -like closures we can -work with any old argument, but for @Int at -like ones the argument has -to be a literal. Reason: @Char@ like closures have an argument type -which is guaranteed in range. - -Because of this, we use can safely return an addressing mode. - -We don't support this optimisation when compiling into Windows DLLs yet -because they don't support cross package data references well. --} - -buildDynCon' dflags platform binder _ _cc con [arg] - | maybeIntLikeCon con - , platformOS platform /= OSMinGW32 || not (positionIndependent dflags) - , NonVoid (StgLitArg (LitNumber LitNumInt val _)) <- arg - , val <= fromIntegral (mAX_INTLIKE dflags) -- Comparisons at type Integer! - , val >= fromIntegral (mIN_INTLIKE dflags) -- ...ditto... - = do { let intlike_lbl = mkCmmClosureLabel rtsUnitId (fsLit "stg_INTLIKE") - val_int = fromIntegral val :: Int - offsetW = (val_int - mIN_INTLIKE dflags) * (fixedHdrSizeW dflags + 1) - -- INTLIKE closures consist of a header and one word payload - intlike_amode = cmmLabelOffW (targetPlatform dflags) intlike_lbl offsetW - ; return ( litIdInfo dflags binder (mkConLFInfo con) intlike_amode - , return mkNop) } - -buildDynCon' dflags platform binder _ _cc con [arg] - | maybeCharLikeCon con - , platformOS platform /= OSMinGW32 || not (positionIndependent dflags) - , NonVoid (StgLitArg (LitChar val)) <- arg - , let val_int = ord val :: Int - , val_int <= mAX_CHARLIKE dflags - , val_int >= mIN_CHARLIKE dflags - = do { let charlike_lbl = mkCmmClosureLabel rtsUnitId (fsLit "stg_CHARLIKE") - offsetW = (val_int - mIN_CHARLIKE dflags) * (fixedHdrSizeW dflags + 1) - -- CHARLIKE closures consist of a header and one word payload - charlike_amode = cmmLabelOffW (targetPlatform dflags) charlike_lbl offsetW - ; return ( litIdInfo dflags binder (mkConLFInfo con) charlike_amode - , return mkNop) } +buildDynCon' dflags binder _ _cc con args + | Just cgInfo <- precomputedStaticConInfo_maybe dflags binder con args + -- , pprTrace "noCodeLocal:" (ppr (binder,con,args,cgInfo)) True + = return (cgInfo, return mkNop) -------- buildDynCon': the general case ----------- -buildDynCon' dflags _ binder actually_bound ccs con args +buildDynCon' dflags binder actually_bound ccs con args = do { (id_info, reg) <- rhsIdInfo binder lf_info ; return (id_info, gen_code reg) } @@ -243,6 +193,149 @@ buildDynCon' dflags _ binder actually_bound ccs con args blame_cc = use_cc -- cost-centre on which to blame the alloc (same) +{- Note [Precomputed static closures] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For Char/Int closures there are some value closures +built into the RTS. This is the case for all values in +the range mINT_INTLIKE .. mAX_INTLIKE (or CHARLIKE). +See Note [CHARLIKE and INTLIKE closures.] in the RTS code. + +Similarly zero-arity constructors have a closure +in their defining Module we can use. + +If possible we prefer to refer to those existing +closure instead of building new ones. + +This is true at compile time where we do this replacement +in this module. +But also at runtime where the GC does the same (but only for +INT/CHAR closures). + +`precomputedStaticConInfo_maybe` checks if a given constructor application +can be replaced with a reference to a existing static closure. + +If so the code will reference the existing closure when accessing +the binding. +Unless the binding is visible to other modules we also generate +no code for the binding itself. We can do this since then we can +always reference the existing closure. + +See Note [About the NameSorts] for the definition of external names. +For external bindings we must still generate a closure, +but won't use it inside this module. +This can sometimes reduce cache pressure. Since: +* If somebody uses the exported binding: + + This module will reference the existing closure. + + GC will reference the existing closure. + + The importing module will reference the built closure. +* If nobody uses the exported binding: + + This module will reference the RTS closures. + + GC references the RTS closures + +In the later case we avoided loading the built closure into the cache which +is what we optimize for here. + +Consider this example using Ints. + + module M(externalInt, foo, bar) where + + externalInt = 1 :: Int + internalInt = 1 :: Int + { -# NOINLINE foo #- } + foo = Just internalInt :: Maybe Int + bar = Just externalInt + + ==================== STG: ==================== + externalInt = I#! [1#]; + + bar = Just! [externalInt]; + + internalInt_rc = I#! [2#]; + + foo = Just! [internalInt_rc]; + +For externally visible bindings we must generate closures +since those may be referenced by their symbol `_closure` +when imported. + +`externalInt` is visible to other modules so we generate a closure: + + [section ""data" . M.externalInt_closure" { + M.externalInt_closure: + const GHC.Types.I#_con_info; + const 1; + }] + +It will be referenced inside this module via `M.externalInt_closure+1` + +`internalInt` is however a internal name. As such we generate no code for +it. References to it are replaced with references to the static closure as +we can see in the closure built for `foo`: + + [section ""data" . M.foo_closure" { + M.foo_closure: + const GHC.Maybe.Just_con_info; + const stg_INTLIKE_closure+289; // == I# 2 + const 3; + }] + +This holds for both local and top level bindings. + +We don't support this optimization when compiling into Windows DLLs yet +because they don't support cross package data references well. +-} + +-- (precomputedStaticConInfo_maybe dflags id con args) +-- returns (Just cg_id_info) +-- if there is a precomputed static closure for (con args). +-- In that case, cg_id_info addresses it. +-- See Note [Precomputed static closures] +precomputedStaticConInfo_maybe :: DynFlags -> Id -> DataCon -> [NonVoid StgArg] -> Maybe CgIdInfo +precomputedStaticConInfo_maybe dflags binder con [] +-- Nullary constructors + | isNullaryRepDataCon con + = Just $ litIdInfo dflags binder (mkConLFInfo con) + (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) +precomputedStaticConInfo_maybe dflags binder con [arg] + -- Int/Char values with existing closures in the RTS + | intClosure || charClosure + , platformOS platform /= OSMinGW32 || not (positionIndependent dflags) + , Just val <- getClosurePayload arg + , inRange val + = let intlike_lbl = mkCmmClosureLabel rtsUnitId (fsLit label) + val_int = fromIntegral val :: Int + offsetW = (val_int - (fromIntegral min_static_range)) * (fixedHdrSizeW dflags + 1) + -- INTLIKE/CHARLIKE closures consist of a header and one word payload + static_amode = cmmLabelOffW platform intlike_lbl offsetW + in Just $ litIdInfo dflags binder (mkConLFInfo con) static_amode + where + platform = targetPlatform dflags + intClosure = maybeIntLikeCon con + charClosure = maybeCharLikeCon con + getClosurePayload (NonVoid (StgLitArg (LitNumber LitNumInt val _))) = Just val + getClosurePayload (NonVoid (StgLitArg (LitChar val))) = Just $ (fromIntegral . ord $ val) + getClosurePayload _ = Nothing + -- Avoid over/underflow by comparisons at type Integer! + inRange :: Integer -> Bool + inRange val + = val >= min_static_range && val <= max_static_range + + min_static_range :: Integer + min_static_range + | intClosure = fromIntegral (mIN_INTLIKE dflags) + | charClosure = fromIntegral (mIN_CHARLIKE dflags) + | otherwise = panic "precomputedStaticConInfo_maybe: Unknown closure type" + max_static_range + | intClosure = fromIntegral (mAX_INTLIKE dflags) + | charClosure = fromIntegral (mAX_CHARLIKE dflags) + | otherwise = panic "precomputedStaticConInfo_maybe: Unknown closure type" + label + | intClosure = "stg_INTLIKE" + | charClosure = "stg_CHARLIKE" + | otherwise = panic "precomputedStaticConInfo_maybe: Unknown closure type" + +precomputedStaticConInfo_maybe _ _ _ _ = Nothing --------------------------------------------------------------- -- Binding constructor arguments ===================================== rts/StgMiscClosures.cmm ===================================== @@ -695,7 +695,7 @@ INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "C { foreign "C" barf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1) never returns; } /* ---------------------------------------------------------------------------- - CHARLIKE and INTLIKE closures. + Note [CHARLIKE and INTLIKE closures.] These are static representations of Chars and small Ints, so that we can remove dynamic Chars and Ints during garbage collection and ===================================== testsuite/tests/codeGen/should_compile/T15155l.hs ===================================== @@ -6,6 +6,6 @@ newtype A = A Int newtype B = B A {-# NOINLINE a #-} -a = trace "evaluating a" A 42 +a = trace "evaluating a" A 42000 b = B a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9462452a4843a2c42fe055a0a7e274d5164d1dc0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9462452a4843a2c42fe055a0a7e274d5164d1dc0 You're receiving 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 3 10:27:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:27:08 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Testsuite: measure compiler stats for T16190 Message-ID: <5e870f7c6242e_61673f81ef22dee427210ef@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 28 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Hpc.hs - compiler/GHC/StgToCmm/Prof.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/StgToCmm/Utils.hs - testsuite/tests/perf/compiler/all.T Changes: ===================================== compiler/GHC/Cmm.hs ===================================== @@ -1,5 +1,8 @@ -- Cmm representations using Hoopl's Graph CmmNode e x. {-# LANGUAGE GADTs #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExplicitNamespaces #-} module GHC.Cmm ( -- * Cmm top-level datatypes @@ -7,7 +10,8 @@ module GHC.Cmm ( CmmDecl, CmmDeclSRTs, GenCmmDecl(..), CmmGraph, GenCmmGraph(..), CmmBlock, RawCmmDecl, - Section(..), SectionType(..), CmmStatics(..), RawCmmStatics(..), CmmStatic(..), + Section(..), SectionType(..), + GenCmmStatics(..), type CmmStatics, type RawCmmStatics, CmmStatic(..), isSecConstant, -- ** Blocks containing lists @@ -197,28 +201,31 @@ data Section = Section SectionType CLabel data CmmStatic = CmmStaticLit CmmLit - -- a literal value, size given by cmmLitRep of the literal. + -- ^ a literal value, size given by cmmLitRep of the literal. | CmmUninitialised Int - -- uninitialised data, N bytes long + -- ^ uninitialised data, N bytes long | CmmString ByteString - -- string of 8-bit values only, not zero terminated. + -- ^ string of 8-bit values only, not zero terminated. + | CmmFileEmbed FilePath + -- ^ an embedded binary file -- Static data before SRT generation -data CmmStatics - = CmmStatics - CLabel -- Label of statics - CmmInfoTable - CostCentreStack - [CmmLit] -- Payload - | CmmStaticsRaw - CLabel -- Label of statics - [CmmStatic] -- The static data itself - --- Static data, after SRTs are generated -data RawCmmStatics - = RawCmmStatics - CLabel -- Label of statics - [CmmStatic] -- The static data itself +data GenCmmStatics (rawOnly :: Bool) where + CmmStatics + :: CLabel -- Label of statics + -> CmmInfoTable + -> CostCentreStack + -> [CmmLit] -- Payload + -> GenCmmStatics 'False + + -- | Static data, after SRTs are generated + CmmStaticsRaw + :: CLabel -- Label of statics + -> [CmmStatic] -- The static data itself + -> GenCmmStatics a + +type CmmStatics = GenCmmStatics 'False +type RawCmmStatics = GenCmmStatics 'True -- ----------------------------------------------------------------------------- -- Basic blocks consisting of lists ===================================== compiler/GHC/Cmm/DebugBlock.hs ===================================== @@ -162,7 +162,7 @@ cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes = DebugBlock { dblProcedure = g_entry graph , dblLabel = label , dblCLabel = case info of - Just (RawCmmStatics infoLbl _) -> infoLbl + Just (CmmStaticsRaw infoLbl _) -> infoLbl Nothing | g_entry graph == label -> entryLbl | otherwise -> blockLbl label ===================================== compiler/GHC/Cmm/Info.hs ===================================== @@ -167,7 +167,7 @@ mkInfoTable dflags proc@(CmmProc infos entry_lbl live blocks) rel_std_info = map (makeRelativeRefTo dflags info_lbl) std_info rel_extra_bits = map (makeRelativeRefTo dflags info_lbl) extra_bits -- - return (top_decls, (lbl, RawCmmStatics info_lbl $ map CmmStaticLit $ + return (top_decls, (lbl, CmmStaticsRaw info_lbl $ map CmmStaticLit $ reverse rel_extra_bits ++ rel_std_info)) ----------------------------------------------------- ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -1107,10 +1107,10 @@ updInfoSRTs -> [CmmDeclSRTs] updInfoSRTs _ _ _ _ (CmmData s (CmmStaticsRaw lbl statics)) - = [CmmData s (RawCmmStatics lbl statics)] + = [CmmData s (CmmStaticsRaw lbl statics)] updInfoSRTs dflags _ _ caffy (CmmData s (CmmStatics lbl itbl ccs payload)) - = [CmmData s (RawCmmStatics lbl (map CmmStaticLit field_lits))] + = [CmmData s (CmmStaticsRaw lbl (map CmmStaticLit field_lits))] where caf_info = if caffy then MayHaveCafRefs else NoCafRefs field_lits = mkStaticClosureFields dflags itbl ccs caf_info payload ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1167,7 +1167,7 @@ staticClosure :: UnitId -> FastString -> FastString -> [CmmLit] -> CmmParse () staticClosure pkg cl_label info payload = do dflags <- getDynFlags let lits = mkStaticClosure dflags (mkCmmInfoLabel pkg info) dontCareCCS payload [] [] [] - code $ emitRawDataLits (mkCmmDataLabel pkg cl_label) lits + code $ emitDataLits (mkCmmDataLabel pkg cl_label) lits foreignCall :: String ===================================== compiler/GHC/Cmm/Ppr/Decl.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GADTs #-} + ---------------------------------------------------------------------------- -- -- Pretty-printing of common Cmm types @@ -70,12 +72,9 @@ instance (Outputable d, Outputable info, Outputable i) => Outputable (GenCmmDecl d info i) where ppr t = pprTop t -instance Outputable CmmStatics where +instance Outputable (GenCmmStatics a) where ppr = pprStatics -instance Outputable RawCmmStatics where - ppr = pprRawStatics - instance Outputable CmmStatic where ppr e = sdocWithDynFlags $ \dflags -> pprStatic (targetPlatform dflags) e @@ -142,19 +141,17 @@ instance Outputable ForeignHint where -- following C-- -- -pprStatics :: CmmStatics -> SDoc +pprStatics :: GenCmmStatics a -> SDoc pprStatics (CmmStatics lbl itbl ccs payload) = ppr lbl <> colon <+> ppr itbl <+> ppr ccs <+> ppr payload -pprStatics (CmmStaticsRaw lbl ds) = pprRawStatics (RawCmmStatics lbl ds) - -pprRawStatics :: RawCmmStatics -> SDoc -pprRawStatics (RawCmmStatics lbl ds) = vcat ((ppr lbl <> colon) : map ppr ds) +pprStatics (CmmStaticsRaw lbl ds) = vcat ((ppr lbl <> colon) : map ppr ds) pprStatic :: Platform -> CmmStatic -> SDoc pprStatic platform s = case s of CmmStaticLit lit -> nest 4 $ text "const" <+> pprLit platform lit <> semi CmmUninitialised i -> nest 4 $ text "I8" <> brackets (int i) CmmString s' -> nest 4 $ text "I8[]" <+> text (show s') + CmmFileEmbed path -> nest 4 $ text "incbin " <+> text (show path) -- -------------------------------------------------------------------------- -- data sections ===================================== compiler/GHC/Cmm/Utils.hs ===================================== @@ -20,7 +20,7 @@ module GHC.Cmm.Utils( -- CmmLit zeroCLit, mkIntCLit, mkWordCLit, packHalfWordsCLit, - mkByteStringCLit, + mkByteStringCLit, mkFileEmbedLit, mkDataLits, mkRODataLits, mkStgWordCLit, @@ -195,23 +195,29 @@ zeroExpr platform = CmmLit (zeroCLit platform) mkWordCLit :: Platform -> Integer -> CmmLit mkWordCLit platform wd = CmmInt wd (wordWidth platform) +-- | We make a top-level decl for the string, and return a label pointing to it mkByteStringCLit - :: CLabel -> ByteString -> (CmmLit, GenCmmDecl RawCmmStatics info stmt) --- We have to make a top-level decl for the string, --- and return a literal pointing to it + :: CLabel -> ByteString -> (CmmLit, GenCmmDecl (GenCmmStatics raw) info stmt) mkByteStringCLit lbl bytes - = (CmmLabel lbl, CmmData (Section sec lbl) $ RawCmmStatics lbl [CmmString bytes]) + = (CmmLabel lbl, CmmData (Section sec lbl) $ CmmStaticsRaw lbl [CmmString bytes]) where -- This can not happen for String literals (as there \NUL is replaced by -- C0 80). However, it can happen with Addr# literals. sec = if 0 `BS.elem` bytes then ReadOnlyData else CString -mkDataLits :: Section -> CLabel -> [CmmLit] -> GenCmmDecl RawCmmStatics info stmt --- Build a data-segment data block +-- | We make a top-level decl for the embedded binary file, and return a label pointing to it +mkFileEmbedLit + :: CLabel -> FilePath -> (CmmLit, GenCmmDecl (GenCmmStatics raw) info stmt) +mkFileEmbedLit lbl path + = (CmmLabel lbl, CmmData (Section ReadOnlyData lbl) (CmmStaticsRaw lbl [CmmFileEmbed path])) + + +-- | Build a data-segment data block +mkDataLits :: Section -> CLabel -> [CmmLit] -> GenCmmDecl (GenCmmStatics raw) info stmt mkDataLits section lbl lits - = CmmData section (RawCmmStatics lbl $ map CmmStaticLit lits) + = CmmData section (CmmStaticsRaw lbl $ map CmmStaticLit lits) -mkRODataLits :: CLabel -> [CmmLit] -> GenCmmDecl RawCmmStatics info stmt +mkRODataLits :: CLabel -> [CmmLit] -> GenCmmDecl (GenCmmStatics raw) info stmt -- Build a read-only data block mkRODataLits lbl lits = mkDataLits section lbl lits ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -669,7 +669,7 @@ getRegister' dflags _ (CmmLit (CmmFloat f frep)) = do let format = floatFormat frep code dst = LDATA (Section ReadOnlyData lbl) - (RawCmmStatics lbl [CmmStaticLit (CmmFloat f frep)]) + (CmmStaticsRaw lbl [CmmStaticLit (CmmFloat f frep)]) `consOL` (addr_code `snocOL` LD format dst addr) return (Any format code) @@ -689,7 +689,7 @@ getRegister' dflags platform (CmmLit lit) let rep = cmmLitType platform lit format = cmmTypeFormat rep code dst = - LDATA (Section ReadOnlyData lbl) (RawCmmStatics lbl [CmmStaticLit lit]) + LDATA (Section ReadOnlyData lbl) (CmmStaticsRaw lbl [CmmStaticLit lit]) `consOL` (addr_code `snocOL` LD format dst addr) return (Any format code) @@ -2110,7 +2110,7 @@ generateJumpTableForInstr config (BCTR ids (Just lbl) _) = = CmmStaticLit (CmmLabelDiffOff blockLabel lbl 0 (ncgWordWidth config)) where blockLabel = blockLbl blockid - in Just (CmmData (Section ReadOnlyData lbl) (RawCmmStatics lbl jumpTable)) + in Just (CmmData (Section ReadOnlyData lbl) (CmmStaticsRaw lbl jumpTable)) generateJumpTableForInstr _ _ = Nothing -- ----------------------------------------------------------------------------- @@ -2340,7 +2340,7 @@ coerceInt2FP' ArchPPC fromRep toRep x = do Amode addr addr_code <- getAmode D dynRef let code' dst = code `appOL` maybe_exts `appOL` toOL [ - LDATA (Section ReadOnlyData lbl) $ RawCmmStatics lbl + LDATA (Section ReadOnlyData lbl) $ CmmStaticsRaw lbl [CmmStaticLit (CmmInt 0x43300000 W32), CmmStaticLit (CmmInt 0x80000000 W32)], XORIS itmp src (ImmInt 0x8000), ===================================== compiler/GHC/CmmToAsm/PPC/Ppr.hs ===================================== @@ -61,7 +61,7 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = -- so label needed vcat (map (pprBasicBlock platform top_info) blocks) - Just (RawCmmStatics info_lbl _) -> + Just (CmmStaticsRaw info_lbl _) -> pprSectionAlign config (Section Text info_lbl) $$ (if platformHasSubsectionsViaSymbols platform then ppr (mkDeadStripPreventer info_lbl) <> char ':' @@ -113,7 +113,7 @@ pprBasicBlock platform info_env (BasicBlock blockid instrs) where maybe_infotable = case mapLookup blockid info_env of Nothing -> empty - Just (RawCmmStatics info_lbl info) -> + Just (CmmStaticsRaw info_lbl info) -> pprAlignForSection platform Text $$ vcat (map (pprData platform) info) $$ pprLabel platform info_lbl @@ -122,7 +122,7 @@ pprBasicBlock platform info_env (BasicBlock blockid instrs) pprDatas :: Platform -> RawCmmStatics -> SDoc -- See note [emit-time elimination of static indirections] in CLabel. -pprDatas _platform (RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) +pprDatas _platform (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) | lbl == mkIndStaticInfoLabel , let labelInd (CmmLabelOff l _) = Just l labelInd (CmmLabel l) = Just l @@ -131,11 +131,12 @@ pprDatas _platform (RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticL , alias `mayRedirectTo` ind' = pprGloblDecl alias $$ text ".equiv" <+> ppr alias <> comma <> ppr (CmmLabel ind') -pprDatas platform (RawCmmStatics lbl dats) = vcat (pprLabel platform lbl : map (pprData platform) dats) +pprDatas platform (CmmStaticsRaw lbl dats) = vcat (pprLabel platform lbl : map (pprData platform) dats) pprData :: Platform -> CmmStatic -> SDoc pprData platform d = case d of - CmmString str -> pprBytes str + CmmString str -> pprString str + CmmFileEmbed path -> pprFileEmbed path CmmUninitialised bytes -> text ".space " <> int bytes CmmStaticLit lit -> pprDataItem platform lit ===================================== compiler/GHC/CmmToAsm/PPC/RegInfo.hs ===================================== @@ -48,8 +48,8 @@ shortcutJump _ other = other -- Here because it knows about JumpDest shortcutStatics :: (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics -shortcutStatics fn (RawCmmStatics lbl statics) - = RawCmmStatics lbl $ map (shortcutStatic fn) statics +shortcutStatics fn (CmmStaticsRaw lbl statics) + = CmmStaticsRaw lbl $ map (shortcutStatic fn) statics -- we need to get the jump tables, so apply the mapping to the entries -- of a CmmData too. ===================================== compiler/GHC/CmmToAsm/Ppr.hs ===================================== @@ -14,7 +14,8 @@ module GHC.CmmToAsm.Ppr ( floatToBytes, doubleToBytes, pprASCII, - pprBytes, + pprString, + pprFileEmbed, pprSectionHeader ) @@ -26,11 +27,9 @@ import AsmUtils import GHC.Cmm.CLabel import GHC.Cmm import GHC.CmmToAsm.Config -import GHC.Driver.Session import FastString import Outputable import GHC.Platform -import FileCleanup import qualified Data.Array.Unsafe as U ( castSTUArray ) import Data.Array.ST @@ -43,7 +42,6 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as BS import GHC.Exts import GHC.Word -import System.IO.Unsafe @@ -129,24 +127,18 @@ pprASCII str ] ord0 = 0x30 -- = ord '0' --- | Pretty print binary data. --- --- Use either the ".string" directive or a ".incbin" directive. --- See Note [Embedding large binary blobs] +-- | Emit a ".string" directive +pprString :: ByteString -> SDoc +pprString bs = text "\t.string " <> doubleQuotes (pprASCII bs) + +-- | Emit a ".incbin" directive -- -- A NULL byte is added after the binary data. --- -pprBytes :: ByteString -> SDoc -pprBytes bs = sdocWithDynFlags $ \dflags -> - if binBlobThreshold dflags == 0 - || fromIntegral (BS.length bs) <= binBlobThreshold dflags - then text "\t.string " <> doubleQuotes (pprASCII bs) - else unsafePerformIO $ do - bFile <- newTempName dflags TFL_CurrentModule ".dat" - BS.writeFile bFile bs - return $ text "\t.incbin " - <> pprFilePathString bFile -- proper escape (see #16389) - <> text "\n\t.byte 0" +pprFileEmbed :: FilePath -> SDoc +pprFileEmbed path + = text "\t.incbin " + <> pprFilePathString path -- proper escape (see #16389) + <> text "\n\t.byte 0" {- Note [Embedding large binary blobs] ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -342,7 +342,7 @@ generateJumpTableForInstr :: Platform -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) generateJumpTableForInstr platform (JMP_TBL _ ids label) = let jumpTable = map (jumpTableEntry platform) ids - in Just (CmmData (Section ReadOnlyData label) (RawCmmStatics label jumpTable)) + in Just (CmmData (Section ReadOnlyData label) (CmmStaticsRaw label jumpTable)) generateJumpTableForInstr _ _ = Nothing ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs ===================================== @@ -86,7 +86,7 @@ getRegister (CmmLit (CmmFloat f W32)) = do let code dst = toOL [ -- the data area - LDATA (Section ReadOnlyData lbl) $ RawCmmStatics lbl + LDATA (Section ReadOnlyData lbl) $ CmmStaticsRaw lbl [CmmStaticLit (CmmFloat f W32)], -- load the literal @@ -99,7 +99,7 @@ getRegister (CmmLit (CmmFloat d W64)) = do lbl <- getNewLabelNat tmp <- getNewRegNat II32 let code dst = toOL [ - LDATA (Section ReadOnlyData lbl) $ RawCmmStatics lbl + LDATA (Section ReadOnlyData lbl) $ CmmStaticsRaw lbl [CmmStaticLit (CmmFloat d W64)], SETHI (HI (ImmCLbl lbl)) tmp, LD II64 (AddrRegImm tmp (LO (ImmCLbl lbl))) dst] ===================================== compiler/GHC/CmmToAsm/SPARC/Ppr.hs ===================================== @@ -67,7 +67,7 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = pprLabel platform lbl $$ -- blocks guaranteed not null, so label needed vcat (map (pprBasicBlock platform top_info) blocks) - Just (RawCmmStatics info_lbl _) -> + Just (CmmStaticsRaw info_lbl _) -> (if platformHasSubsectionsViaSymbols platform then pprSectionAlign config dspSection $$ ppr (mkDeadStripPreventer info_lbl) <> char ':' @@ -96,7 +96,7 @@ pprBasicBlock platform info_env (BasicBlock blockid instrs) where maybe_infotable = case mapLookup blockid info_env of Nothing -> empty - Just (RawCmmStatics info_lbl info) -> + Just (CmmStaticsRaw info_lbl info) -> pprAlignForSection Text $$ vcat (map (pprData platform) info) $$ pprLabel platform info_lbl @@ -104,7 +104,7 @@ pprBasicBlock platform info_env (BasicBlock blockid instrs) pprDatas :: Platform -> RawCmmStatics -> SDoc -- See note [emit-time elimination of static indirections] in CLabel. -pprDatas _platform (RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) +pprDatas _platform (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) | lbl == mkIndStaticInfoLabel , let labelInd (CmmLabelOff l _) = Just l labelInd (CmmLabel l) = Just l @@ -113,12 +113,14 @@ pprDatas _platform (RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticL , alias `mayRedirectTo` ind' = pprGloblDecl alias $$ text ".equiv" <+> ppr alias <> comma <> ppr (CmmLabel ind') -pprDatas platform (RawCmmStatics lbl dats) = vcat (pprLabel platform lbl : map (pprData platform) dats) +pprDatas platform (CmmStaticsRaw lbl dats) = vcat (pprLabel platform lbl : map (pprData platform) dats) pprData :: Platform -> CmmStatic -> SDoc -pprData _ (CmmString str) = pprBytes str -pprData _ (CmmUninitialised bytes) = text ".skip " <> int bytes -pprData platform (CmmStaticLit lit) = pprDataItem platform lit +pprData platform d = case d of + CmmString str -> pprString str + CmmFileEmbed path -> pprFileEmbed path + CmmUninitialised bytes -> text ".skip " <> int bytes + CmmStaticLit lit -> pprDataItem platform lit pprGloblDecl :: CLabel -> SDoc pprGloblDecl lbl ===================================== compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs ===================================== @@ -44,8 +44,8 @@ shortcutJump _ other = other shortcutStatics :: (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics -shortcutStatics fn (RawCmmStatics lbl statics) - = RawCmmStatics lbl $ map (shortcutStatic fn) statics +shortcutStatics fn (CmmStaticsRaw lbl statics) + = CmmStaticsRaw lbl $ map (shortcutStatic fn) statics -- we need to get the jump tables, so apply the mapping to the entries -- of a CmmData too. ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1485,7 +1485,7 @@ memConstant align lit = do return (addr, addr_code) else return (ripRel (ImmCLbl lbl), nilOL) let code = - LDATA rosection (align, RawCmmStatics lbl [CmmStaticLit lit]) + LDATA rosection (align, CmmStaticsRaw lbl [CmmStaticLit lit]) `consOL` addr_code return (Amode addr code) @@ -3329,7 +3329,7 @@ createJumpTable config ids section lbl where blockLabel = blockLbl blockid in map jumpTableEntryRel ids | otherwise = map (jumpTableEntry config) ids - in CmmData section (mkAlignment 1, RawCmmStatics lbl jumpTable) + in CmmData section (mkAlignment 1, CmmStaticsRaw lbl jumpTable) extractUnwindPoints :: [Instr] -> [UnwindPoint] extractUnwindPoints instrs = ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -1021,8 +1021,8 @@ shortcutJump fn insn = shortcutJump' fn (setEmpty :: LabelSet) insn -- Here because it knows about JumpDest shortcutStatics :: (BlockId -> Maybe JumpDest) -> (Alignment, RawCmmStatics) -> (Alignment, RawCmmStatics) -shortcutStatics fn (align, RawCmmStatics lbl statics) - = (align, RawCmmStatics lbl $ map (shortcutStatic fn) statics) +shortcutStatics fn (align, CmmStaticsRaw lbl statics) + = (align, CmmStaticsRaw lbl $ map (shortcutStatic fn) statics) -- we need to get the jump tables, so apply the mapping to the entries -- of a CmmData too. ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -93,7 +93,7 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = then ppr (mkAsmTempEndLabel lbl) <> char ':' else empty) $$ pprSizeDecl platform lbl - Just (RawCmmStatics info_lbl _) -> + Just (CmmStaticsRaw info_lbl _) -> pprSectionAlign config (Section Text info_lbl) $$ pprProcAlignment config $$ (if platformHasSubsectionsViaSymbols platform @@ -132,7 +132,7 @@ pprBasicBlock config info_env (BasicBlock blockid instrs) platform = ncgPlatform config maybe_infotable c = case mapLookup blockid info_env of Nothing -> c - Just (RawCmmStatics infoLbl info) -> + Just (CmmStaticsRaw infoLbl info) -> pprAlignForSection platform Text $$ infoTableLoc $$ vcat (map (pprData config) info) $$ @@ -151,7 +151,7 @@ pprBasicBlock config info_env (BasicBlock blockid instrs) pprDatas :: NCGConfig -> (Alignment, RawCmmStatics) -> SDoc -- See note [emit-time elimination of static indirections] in CLabel. -pprDatas _config (_, RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) +pprDatas _config (_, CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) | lbl == mkIndStaticInfoLabel , let labelInd (CmmLabelOff l _) = Just l labelInd (CmmLabel l) = Just l @@ -161,13 +161,14 @@ pprDatas _config (_, RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStatic = pprGloblDecl alias $$ text ".equiv" <+> ppr alias <> comma <> ppr (CmmLabel ind') -pprDatas config (align, (RawCmmStatics lbl dats)) +pprDatas config (align, (CmmStaticsRaw lbl dats)) = vcat (pprAlign platform align : pprLabel platform lbl : map (pprData config) dats) where platform = ncgPlatform config pprData :: NCGConfig -> CmmStatic -> SDoc -pprData _config (CmmString str) = pprBytes str +pprData _config (CmmString str) = pprString str +pprData _config (CmmFileEmbed path) = pprFileEmbed path pprData config (CmmUninitialised bytes) = let platform = ncgPlatform config ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -88,7 +88,7 @@ pprTop dflags = \case (CmmProc infos clbl _in_live_regs graph) -> (case mapLookup (g_entry graph) infos of Nothing -> empty - Just (RawCmmStatics info_clbl info_dat) -> + Just (CmmStaticsRaw info_clbl info_dat) -> pprDataExterns platform info_dat $$ pprWordArray dflags info_is_in_rodata info_clbl info_dat) $$ (vcat [ @@ -111,21 +111,21 @@ pprTop dflags = \case -- We only handle (a) arrays of word-sized things and (b) strings. - (CmmData section (RawCmmStatics lbl [CmmString str])) -> + (CmmData section (CmmStaticsRaw lbl [CmmString str])) -> pprExternDecl platform lbl $$ hcat [ pprLocalness lbl, pprConstness (isSecConstant section), text "char ", ppr lbl, text "[] = ", pprStringInCStyle str, semi ] - (CmmData section (RawCmmStatics lbl [CmmUninitialised size])) -> + (CmmData section (CmmStaticsRaw lbl [CmmUninitialised size])) -> pprExternDecl platform lbl $$ hcat [ pprLocalness lbl, pprConstness (isSecConstant section), text "char ", ppr lbl, brackets (int size), semi ] - (CmmData section (RawCmmStatics lbl lits)) -> + (CmmData section (CmmStaticsRaw lbl lits)) -> pprDataExterns platform lits $$ pprWordArray dflags (isSecConstant section) lbl lits where @@ -574,6 +574,7 @@ pprStatic dflags s = case s of -- these should be inlined, like the old .hc CmmString s' -> nest 4 (mkW_ <> parens(pprStringInCStyle s')) + CmmFileEmbed {} -> panic "Unexpected CmmFileEmbed literal" -- --------------------------------------------------------------------------- ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -121,9 +121,9 @@ llvmGroupLlvmGens cmm = do let split (CmmData s d' ) = return $ Just (s, d') split (CmmProc h l live g) = do -- Set function type - let l' = case mapLookup (g_entry g) h of + let l' = case mapLookup (g_entry g) h :: Maybe RawCmmStatics of Nothing -> l - Just (RawCmmStatics info_lbl _) -> info_lbl + Just (CmmStaticsRaw info_lbl _) -> info_lbl lml <- strCLabel_llvm l' funInsert lml =<< llvmFunTy live return Nothing ===================================== compiler/GHC/CmmToLlvm/Data.hs ===================================== @@ -44,7 +44,7 @@ linkage lbl = if externallyVisibleCLabel lbl -- | Pass a CmmStatic section to an equivalent Llvm code. genLlvmData :: (Section, RawCmmStatics) -> LlvmM LlvmData -- See note [emit-time elimination of static indirections] in CLabel. -genLlvmData (_, RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) +genLlvmData (_, CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _]) | lbl == mkIndStaticInfoLabel , let labelInd (CmmLabelOff l _) = Just l labelInd (CmmLabel l) = Just l @@ -67,7 +67,7 @@ genLlvmData (_, RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit i pure ([LMGlobal aliasDef $ Just orig], [tyAlias]) -genLlvmData (sec, RawCmmStatics lbl xs) = do +genLlvmData (sec, CmmStaticsRaw lbl xs) = do label <- strCLabel_llvm lbl static <- mapM genData xs lmsec <- llvmSection sec @@ -132,6 +132,7 @@ llvmSection (Section t suffix) = do -- | Handle static data genData :: CmmStatic -> LlvmM LlvmStatic +genData (CmmFileEmbed {}) = panic "Unexpected CmmFileEmbed literal" genData (CmmString str) = do let v = map (\x -> LMStaticLit $ LMIntLit (fromIntegral x) i8) (BS.unpack str) ===================================== compiler/GHC/CmmToLlvm/Ppr.hs ===================================== @@ -46,7 +46,7 @@ pprLlvmCmmDecl (CmmData _ lmdata) pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks)) = do let lbl = case mb_info of Nothing -> entry_lbl - Just (RawCmmStatics info_lbl _) -> info_lbl + Just (CmmStaticsRaw info_lbl _) -> info_lbl link = if externallyVisibleCLabel lbl then ExternallyVisible else Internal @@ -63,7 +63,7 @@ pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks)) -- generate the info table prefix <- case mb_info of Nothing -> return Nothing - Just (RawCmmStatics _ statics) -> do + Just (CmmStaticsRaw _ statics) -> do infoStatics <- mapM genData statics let infoTy = LMStruct $ map getStatType infoStatics return $ Just $ LMStaticStruc infoStatics infoTy ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -27,6 +27,7 @@ import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky import GHC.Cmm +import GHC.Cmm.Utils import GHC.Cmm.CLabel import GHC.Stg.Syntax @@ -45,6 +46,7 @@ import Outputable import Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) +import FileCleanup import OrdList import GHC.Cmm.Graph @@ -52,6 +54,8 @@ import GHC.Cmm.Graph import Data.IORef import Control.Monad (when,void) import Util +import System.IO.Unsafe +import qualified Data.ByteString as BS codeGen :: DynFlags -> Module @@ -133,12 +137,24 @@ cgTopBinding dflags (StgTopLifted (StgRec pairs)) ; sequence_ fcodes } -cgTopBinding dflags (StgTopStringLit id str) - = do { let label = mkBytesLabel (idName id) - ; let (lit, decl) = mkByteStringCLit label str - ; emitDecl decl - ; addBindC (litIdInfo dflags id mkLFStringLit lit) - } +cgTopBinding dflags (StgTopStringLit id str) = do + let label = mkBytesLabel (idName id) + -- emit either a CmmString literal or dump the string in a file and emit a + -- CmmFileEmbed literal. + -- See Note [Embedding large binary blobs] in GHC.CmmToAsm.Ppr + let isNCG = platformMisc_ghcWithNativeCodeGen $ platformMisc dflags + isSmall = fromIntegral (BS.length str) <= binBlobThreshold dflags + asString = binBlobThreshold dflags == 0 || isSmall + + (lit,decl) = if not isNCG || asString + then mkByteStringCLit label str + else mkFileEmbedLit label $ unsafePerformIO $ do + bFile <- newTempName dflags TFL_CurrentModule ".dat" + BS.writeFile bFile str + return bFile + emitDecl decl + addBindC (litIdInfo dflags id mkLFStringLit lit) + cgTopRhs :: DynFlags -> RecFlag -> Id -> CgStgRhs -> (CgIdInfo, FCode ()) -- The Id is passed along for setting up a binding... @@ -177,7 +193,7 @@ mkModuleInit cost_centre_info this_mod hpc_info cgEnumerationTyCon :: TyCon -> FCode () cgEnumerationTyCon tycon = do dflags <- getDynFlags - emitRawRODataLits (mkLocalClosureTableLabel (tyConName tycon) NoCafRefs) + emitRODataLits (mkLocalClosureTableLabel (tyConName tycon) NoCafRefs) [ CmmLabelOff (mkLocalClosureLabel (dataConName con) NoCafRefs) (tagForCon dflags con) | con <- tyConDataCons tycon] ===================================== compiler/GHC/StgToCmm/Hpc.hs ===================================== @@ -35,15 +35,15 @@ mkTickBox platform mod n (CmmLit $ CmmLabel $ mkHpcTicksLabel $ mod) n +-- | Emit top-level tables for HPC and return code to initialise initHpc :: Module -> HpcInfo -> FCode () --- Emit top-level tables for HPC and return code to initialise initHpc _ (NoHpcInfo {}) = return () initHpc this_mod (HpcInfo tickCount _hashNo) = do dflags <- getDynFlags when (gopt Opt_Hpc dflags) $ - emitRawDataLits (mkHpcTicksLabel this_mod) - [ (CmmInt 0 W64) - | _ <- take tickCount [0 :: Int ..] - ] + emitDataLits (mkHpcTicksLabel this_mod) + [ (CmmInt 0 W64) + | _ <- take tickCount [0 :: Int ..] + ] ===================================== compiler/GHC/StgToCmm/Prof.hs ===================================== @@ -236,7 +236,7 @@ emitCostCentreDecl cc = do is_caf, -- StgInt is_caf zero platform -- struct _CostCentre *link ] - ; emitRawDataLits (mkCCLabel cc) lits + ; emitDataLits (mkCCLabel cc) lits } emitCostCentreStackDecl :: CostCentreStack -> FCode () @@ -253,7 +253,7 @@ emitCostCentreStackDecl ccs -- layouts of structs containing long-longs, simply -- pad out the struct with zero words until we hit the -- size of the overall struct (which we get via DerivedConstants.h) - emitRawDataLits (mkCCSLabel ccs) (mk_lits cc) + emitDataLits (mkCCSLabel ccs) (mk_lits cc) Nothing -> pprPanic "emitCostCentreStackDecl" (ppr ccs) zero :: Platform -> CmmLit ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -243,7 +243,7 @@ emitTickyCounter cloType name args ; fun_descr_lit <- newStringCLit $ showSDocDebug dflags ppr_for_ticky_name ; arg_descr_lit <- newStringCLit $ map (showTypeCategory . idType . fromNonVoid) args - ; emitRawDataLits ctr_lbl + ; emitDataLits ctr_lbl -- Must match layout of includes/rts/Ticky.h's StgEntCounter -- -- krc: note that all the fields are I32 now; some were I16 @@ -256,7 +256,7 @@ emitTickyCounter cloType name args arg_descr_lit, zeroCLit platform, -- Entries into this thing zeroCLit platform, -- Heap allocated by this thing - zeroCLit platform -- Link to next StgEntCounter + zeroCLit platform -- Link to next StgEntCounter ] } ===================================== compiler/GHC/StgToCmm/Utils.hs ===================================== @@ -11,8 +11,7 @@ module GHC.StgToCmm.Utils ( cgLit, mkSimpleLit, - emitRawDataLits, mkRawDataLits, - emitRawRODataLits, mkRawRODataLits, + emitDataLits, emitRODataLits, emitDataCon, emitRtsCall, emitRtsCallWithResult, emitRtsCallGen, assignTemp, newTemp, @@ -38,7 +37,6 @@ module GHC.StgToCmm.Utils ( cmmUntag, cmmIsTagged, addToMem, addToMemE, addToMemLblE, addToMemLbl, - mkWordCLit, mkByteStringCLit, newStringCLit, newByteStringCLit, blankWord, @@ -60,7 +58,7 @@ import GHC.Cmm.BlockId import GHC.Cmm.Graph as CmmGraph import GHC.Platform.Regs import GHC.Cmm.CLabel -import GHC.Cmm.Utils hiding (mkDataLits, mkRODataLits, mkByteStringCLit) +import GHC.Cmm.Utils import GHC.Cmm.Switch import GHC.StgToCmm.CgUtils @@ -83,7 +81,6 @@ import GHC.Types.CostCentre import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS8 -import qualified Data.ByteString as BS import qualified Data.Map as M import Data.Char import Data.List @@ -276,40 +273,13 @@ callerSaveVolatileRegs dflags = (caller_save, caller_load) -- ------------------------------------------------------------------------- -mkRawDataLits :: Section -> CLabel -> [CmmLit] -> GenCmmDecl CmmStatics info stmt --- Build a data-segment data block -mkRawDataLits section lbl lits - = CmmData section (CmmStaticsRaw lbl (map CmmStaticLit lits)) +-- | Emit a data-segment data block +emitDataLits :: CLabel -> [CmmLit] -> FCode () +emitDataLits lbl lits = emitDecl (mkDataLits (Section Data lbl) lbl lits) -mkRawRODataLits :: CLabel -> [CmmLit] -> GenCmmDecl CmmStatics info stmt --- Build a read-only data block -mkRawRODataLits lbl lits - = mkRawDataLits section lbl lits - where - section | any needsRelocation lits = Section RelocatableReadOnlyData lbl - | otherwise = Section ReadOnlyData lbl - needsRelocation (CmmLabel _) = True - needsRelocation (CmmLabelOff _ _) = True - needsRelocation _ = False - -mkByteStringCLit - :: CLabel -> ByteString -> (CmmLit, GenCmmDecl CmmStatics info stmt) --- We have to make a top-level decl for the string, --- and return a literal pointing to it -mkByteStringCLit lbl bytes - = (CmmLabel lbl, CmmData (Section sec lbl) (CmmStaticsRaw lbl [CmmString bytes])) - where - -- This can not happen for String literals (as there \NUL is replaced by - -- C0 80). However, it can happen with Addr# literals. - sec = if 0 `BS.elem` bytes then ReadOnlyData else CString - -emitRawDataLits :: CLabel -> [CmmLit] -> FCode () --- Emit a data-segment data block -emitRawDataLits lbl lits = emitDecl (mkRawDataLits (Section Data lbl) lbl lits) - -emitRawRODataLits :: CLabel -> [CmmLit] -> FCode () --- Emit a read-only data block -emitRawRODataLits lbl lits = emitDecl (mkRawRODataLits lbl lits) +-- | Emit a read-only data block +emitRODataLits :: CLabel -> [CmmLit] -> FCode () +emitRODataLits lbl lits = emitDecl (mkRODataLits lbl lits) emitDataCon :: CLabel -> CmmInfoTable -> CostCentreStack -> [CmmLit] -> FCode () emitDataCon lbl itbl ccs payload = emitDecl (CmmData (Section Data lbl) (CmmStatics lbl itbl ccs payload)) ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -355,7 +355,7 @@ test ('WWRec', ['-v0 -O']) test('T16190', - [req_th, collect_stats()], + [req_th, collect_compiler_stats()], multimod_compile, ['T16190.hs', '-v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a214d2142c1bafa71fe52cb3823351ff9322d336...cc2918a0407e1581e824ebd90a1fcbb0637d5744 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a214d2142c1bafa71fe52cb3823351ff9322d336...cc2918a0407e1581e824ebd90a1fcbb0637d5744 You're receiving 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 3 10:26:21 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:26:21 -0400 Subject: [Git][ghc/ghc][master] Add singleton to NonEmpty in libraries/base Message-ID: <5e870f4dd9fb0_61673f81bb9e8b0427181d3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - 2 changed files: - libraries/base/Data/List/NonEmpty.hs - libraries/base/changelog.md Changes: ===================================== libraries/base/Data/List/NonEmpty.hs ===================================== @@ -42,6 +42,7 @@ module Data.List.NonEmpty ( , tail -- :: NonEmpty a -> [a] , last -- :: NonEmpty a -> a , init -- :: NonEmpty a -> [a] + , singleton -- :: a -> NonEmpty a , (<|), cons -- :: a -> NonEmpty a -> NonEmpty a , uncons -- :: NonEmpty a -> (a, Maybe (NonEmpty a)) , unfoldr -- :: (a -> (b, Maybe a)) -> a -> NonEmpty b @@ -168,6 +169,12 @@ last ~(a :| as) = List.last (a : as) init :: NonEmpty a -> [a] init ~(a :| as) = List.init (a : as) +-- | Construct a 'NonEmpty' list from a single element. +-- +-- @since 4.15 +singleton :: a -> NonEmpty a +singleton a = a :| [] + -- | Prepend an element to the stream. (<|) :: a -> NonEmpty a -> NonEmpty a a <| ~(b :| bs) = a :| b : bs ===================================== libraries/base/changelog.md ===================================== @@ -9,6 +9,9 @@ * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: Strict IO variants of `hGetContents`, `getContents`, and `readFile`. + * Add `singleton` function for `Data.List.NonEmpty`. + + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a214d2142c1bafa71fe52cb3823351ff9322d336 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a214d2142c1bafa71fe52cb3823351ff9322d336 You're receiving 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 3 10:27:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:27:42 -0400 Subject: [Git][ghc/ghc][master] Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs Message-ID: <5e870f9e2a5ea_6167136dfb9c27263fc@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1 changed file: - libraries/base/Control/Monad/ST/Lazy/Imp.hs Changes: ===================================== libraries/base/Control/Monad/ST/Lazy/Imp.hs ===================================== @@ -45,10 +45,10 @@ import qualified Control.Monad.ST.Unsafe as ST import qualified GHC.ST as GHC.ST import GHC.Base --- | The lazy @'ST' monad. --- The ST monad allows for destructive updates, but is escapable (unlike IO). +-- | The lazy @'ST'@ monad. +-- The ST monad allows for destructive updates, but is escapable (unlike @IO@). -- A computation of type @'ST' s a@ returns a value of type @a@, and --- execute in "thread" @s at . The @s@ parameter is either +-- executes in "thread" @s at . The @s@ parameter is either -- -- * an uninstantiated type variable (inside invocations of 'runST'), or -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e60273db47364fc08aeb5a389caf67559e0d353 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e60273db47364fc08aeb5a389caf67559e0d353 You're receiving 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 3 10:28:16 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:28:16 -0400 Subject: [Git][ghc/ghc][master] Turn newlines into spaces for hadrian/ghci. Message-ID: <5e870fc0dce8e_61673f8199536d9427295ce@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 2 changed files: - hadrian/ghci-cabal - hadrian/ghci-stack Changes: ===================================== hadrian/ghci-cabal ===================================== @@ -2,5 +2,6 @@ set -e -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@")" +# Replace newlines with spaces, as these otherwise break the ghci invocation on windows. +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m ===================================== hadrian/ghci-stack ===================================== @@ -2,5 +2,6 @@ set -e -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@")" +# Replace newlines with spaces, as these otherwise break the ghci invocation on windows. +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b7e8a94cb3334fc0e513dec2db323f32c3a0713 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b7e8a94cb3334fc0e513dec2db323f32c3a0713 You're receiving 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 3 10:28:57 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 06:28:57 -0400 Subject: [Git][ghc/ghc][master] Major improvements to the specialiser Message-ID: <5e870fe9b12f6_6167134ebbc4273309a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 15 changed files: - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/Binds.hs - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/Makefile - + testsuite/tests/simplCore/should_compile/T17810.hs - + testsuite/tests/simplCore/should_compile/T17810a.hs - + testsuite/tests/simplCore/should_compile/T17930.hs - + testsuite/tests/simplCore/should_compile/T17930.stderr - + testsuite/tests/simplCore/should_compile/T17966.hs - + testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_compile/spec004.hs - + testsuite/tests/simplCore/should_compile/spec004.stderr Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Core.Predicate import GHC.Types.Module( Module, HasModule(..) ) import GHC.Core.Coercion( Coercion ) import GHC.Core.Op.Monad -import qualified GHC.Core.Subst +import qualified GHC.Core.Subst as Core import GHC.Core.Unfold import GHC.Types.Var ( isLocalVar ) import GHC.Types.Var.Set @@ -30,13 +30,15 @@ import GHC.Types.Var.Env import GHC.Core import GHC.Core.Rules import GHC.Core.SimpleOpt ( collectBindersPushingCo ) -import GHC.Core.Utils ( exprIsTrivial, mkCast, exprType ) +import GHC.Core.Utils ( exprIsTrivial, getIdFromTrivialExpr_maybe + , mkCast, exprType ) import GHC.Core.FVs import GHC.Core.Arity ( etaExpandToJoinPointRule ) import GHC.Types.Unique.Supply import GHC.Types.Name import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import Maybes ( mapMaybe, isJust ) +import TysPrim ( voidPrimTy ) +import Maybes ( mapMaybe, maybeToList, isJust ) import MonadUtils ( foldlM ) import GHC.Types.Basic import GHC.Driver.Types @@ -606,7 +608,7 @@ specProgram guts@(ModGuts { mg_module = this_mod -- accidentally re-use a unique that's already in use -- Easiest thing is to do it all at once, as if all the top-level -- decls were mutually recursive - top_env = SE { se_subst = GHC.Core.Subst.mkEmptySubst $ mkInScopeSet $ mkVarSet $ + top_env = SE { se_subst = Core.mkEmptySubst $ mkInScopeSet $ mkVarSet $ bindersOfBinds binds , se_interesting = emptyVarSet } @@ -636,189 +638,12 @@ bitten by such instances to revert to the pre-7.10 behavior. See #10491 -} --- | An argument that we might want to specialise. --- See Note [Specialising Calls] for the nitty gritty details. -data SpecArg - = - -- | Type arguments that should be specialised, due to appearing - -- free in the type of a 'SpecDict'. - SpecType Type - -- | Type arguments that should remain polymorphic. - | UnspecType - -- | Dictionaries that should be specialised. - | SpecDict DictExpr - -- | Value arguments that should not be specialised. - | UnspecArg - -instance Outputable SpecArg where - ppr (SpecType t) = text "SpecType" <+> ppr t - ppr UnspecType = text "UnspecType" - ppr (SpecDict d) = text "SpecDict" <+> ppr d - ppr UnspecArg = text "UnspecArg" - -getSpecDicts :: [SpecArg] -> [DictExpr] -getSpecDicts = mapMaybe go - where - go (SpecDict d) = Just d - go _ = Nothing - -getSpecTypes :: [SpecArg] -> [Type] -getSpecTypes = mapMaybe go - where - go (SpecType t) = Just t - go _ = Nothing - -isUnspecArg :: SpecArg -> Bool -isUnspecArg UnspecArg = True -isUnspecArg UnspecType = True -isUnspecArg _ = False - -isValueArg :: SpecArg -> Bool -isValueArg UnspecArg = True -isValueArg (SpecDict _) = True -isValueArg _ = False - --- | Given binders from an original function 'f', and the 'SpecArg's --- corresponding to its usage, compute everything necessary to build --- a specialisation. --- --- We will use a running example. Consider the function --- --- foo :: forall a b. Eq a => Int -> blah --- foo @a @b dEqA i = blah --- --- which is called with the 'CallInfo' --- --- [SpecType T1, UnspecType, SpecDict dEqT1, UnspecArg] --- --- We'd eventually like to build the RULE --- --- RULE "SPEC foo @T1 _" --- forall @a @b (dEqA' :: Eq a). --- foo @T1 @b dEqA' = $sfoo @b --- --- and the specialisation '$sfoo' --- --- $sfoo :: forall b. Int -> blah --- $sfoo @b = \i -> SUBST[a->T1, dEqA->dEqA'] blah --- --- The cases for 'specHeader' below are presented in the same order as this --- running example. The result of 'specHeader' for this example is as follows: --- --- ( -- Returned arguments --- env + [a -> T1, deqA -> dEqA'] --- , [] --- --- -- RULE helpers --- , [b, dx', i] --- , [T1, b, dx', i] --- --- -- Specialised function helpers --- , [b, i] --- , [dx] --- , [T1, b, dx_spec, i] --- ) -specHeader - :: SpecEnv - -> [CoreBndr] -- The binders from the original function 'f' - -> [SpecArg] -- From the CallInfo - -> SpecM ( -- Returned arguments - SpecEnv -- Substitution to apply to the body of 'f' - , [CoreBndr] -- All the remaining unspecialised args from the original function 'f' - - -- RULE helpers - , [CoreBndr] -- Binders for the RULE - , [CoreArg] -- Args for the LHS of the rule - - -- Specialised function helpers - , [CoreBndr] -- Binders for $sf - , [DictBind] -- Auxiliary dictionary bindings - , [CoreExpr] -- Specialised arguments for unfolding - ) - --- We want to specialise on type 'T1', and so we must construct a substitution --- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding --- details. -specHeader env (bndr : bndrs) (SpecType t : args) - = do { let env' = extendTvSubstList env [(bndr, t)] - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , rule_bs - , Type t : rule_es - , bs' - , dx - , Type t : spec_args - ) - } - --- Next we have a type that we don't want to specialise. We need to perform --- a substitution on it (in case the type refers to 'a'). Additionally, we need --- to produce a binder, LHS argument and RHS argument for the resulting rule, --- /and/ a binder for the specialised body. -specHeader env (bndr : bndrs) (UnspecType : args) - = do { let (env', bndr') = substBndr env bndr - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , bndr' : rule_bs - , varToCoreExpr bndr' : rule_es - , bndr' : bs' - , dx - , varToCoreExpr bndr' : spec_args - ) - } - --- Next we want to specialise the 'Eq a' dict away. We need to construct --- a wildcard binder to match the dictionary (See Note [Specialising Calls] for --- the nitty-gritty), as a LHS rule and unfolding details. -specHeader env (bndr : bndrs) (SpecDict d : args) - = do { inst_dict_id <- newDictBndr env bndr - ; let (rhs_env2, dx_binds, spec_dict_args') - = bindAuxiliaryDicts env [bndr] [d] [inst_dict_id] - ; (env', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader rhs_env2 bndrs args - ; pure ( env' - , unused_bndrs - -- See Note [Evidence foralls] - , exprFreeIdsList (varToCoreExpr inst_dict_id) ++ rule_bs - , varToCoreExpr inst_dict_id : rule_es - , bs' - , dx_binds ++ dx - , spec_dict_args' ++ spec_args - ) - } - --- Finally, we have the unspecialised argument 'i'. We need to produce --- a binder, LHS and RHS argument for the RULE, and a binder for the --- specialised body. --- --- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is --- why 'i' doesn't appear in our RULE above. But we have no guarantee that --- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so --- this case must be here. -specHeader env (bndr : bndrs) (UnspecArg : args) - = do { let (env', bndr') = substBndr env bndr - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , bndr' : rule_bs - , varToCoreExpr bndr' : rule_es - , bndr' : bs' - , dx - , varToCoreExpr bndr' : spec_args - ) - } - --- Return all remaining binders from the original function. These have the --- invariant that they should all correspond to unspecialised arguments, so --- it's safe to stop processing at this point. -specHeader env bndrs [] = pure (env, bndrs, [], [], [], [], []) -specHeader env [] _ = pure (env, [], [], [], [], [], []) +{- ********************************************************************* +* * + Specialising imported functions +* * +********************************************************************* -} -- | Specialise a set of calls to imported bindings specImports :: DynFlags @@ -1035,7 +860,7 @@ Avoiding this recursive specialisation loop is the reason for the -} data SpecEnv - = SE { se_subst :: GHC.Core.Subst.Subst + = SE { se_subst :: Core.Subst -- We carry a substitution down: -- a) we must clone any binding that might float outwards, -- to avoid name clashes @@ -1049,8 +874,14 @@ data SpecEnv -- See Note [Interesting dictionary arguments] } +instance Outputable SpecEnv where + ppr (SE { se_subst = subst, se_interesting = interesting }) + = text "SE" <+> braces (sep $ punctuate comma + [ text "subst =" <+> ppr subst + , text "interesting =" <+> ppr interesting ]) + specVar :: SpecEnv -> Id -> CoreExpr -specVar env v = GHC.Core.Subst.lookupIdSubst (text "specVar") (se_subst env) v +specVar env v = Core.lookupIdSubst (text "specVar") (se_subst env) v specExpr :: SpecEnv -> CoreExpr -> SpecM (CoreExpr, UsageDetails) @@ -1080,12 +911,10 @@ specExpr env expr@(App {}) go other _ = specExpr env other ---------------- Lambda/case require dumping of usage details -------------------- -specExpr env e@(Lam _ _) = do - (body', uds) <- specExpr env' body - let (free_uds, dumped_dbs) = dumpUDs bndrs' uds - return (mkLams bndrs' (wrapDictBindsE dumped_dbs body'), free_uds) +specExpr env e@(Lam {}) + = specLam env' bndrs' body where - (bndrs, body) = collectBinders e + (bndrs, body) = collectBinders e (env', bndrs') = substBndrs env bndrs -- More efficient to collect a group of binders together all at once -- and we don't want to split a lambda group with dumped bindings @@ -1111,6 +940,18 @@ specExpr env (Let bind body) -- All done ; return (foldr Let body' binds', uds) } +-------------- +specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails) +-- The binders have been substituted, but the body has not +specLam env bndrs body + | null bndrs + = specExpr env body + | otherwise + = do { (body', uds) <- specExpr env body + ; let (free_uds, dumped_dbs) = dumpUDs bndrs uds + ; return (mkLams bndrs (wrapDictBindsE dumped_dbs body'), free_uds) } + +-------------- specTickish :: SpecEnv -> Tickish Id -> Tickish Id specTickish env (Breakpoint ix ids) = Breakpoint ix [ id' | id <- ids, Var id' <- [specVar env id]] @@ -1118,6 +959,7 @@ specTickish env (Breakpoint ix ids) -- should never happen, but it's harmless to drop them anyway. specTickish _ other_tickish = other_tickish +-------------- specCase :: SpecEnv -> CoreExpr -- Scrutinee, already done -> Id -> [CoreAlt] @@ -1143,7 +985,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] subst_prs = (case_bndr, Var case_bndr_flt) : [ (arg, Var sc_flt) | (arg, Just sc_flt) <- args `zip` mb_sc_flts ] - env_rhs' = env_rhs { se_subst = GHC.Core.Subst.extendIdSubstList (se_subst env_rhs) subst_prs + env_rhs' = env_rhs { se_subst = Core.extendIdSubstList (se_subst env_rhs) subst_prs , se_interesting = se_interesting env_rhs `extendVarSetList` (case_bndr_flt : sc_args_flt) } @@ -1240,7 +1082,13 @@ specBind :: SpecEnv -- Use this for RHSs -- No calls for binders of this bind specBind rhs_env (NonRec fn rhs) body_uds = do { (rhs', rhs_uds) <- specExpr rhs_env rhs - ; (fn', spec_defns, body_uds1) <- specDefn rhs_env body_uds fn rhs + + ; let zapped_fn = zapIdDemandInfo fn + -- We zap the demand info because the binding may float, + -- which would invaidate the demand info (see #17810 for example). + -- Destroying demand info is not terrible; specialisation is + -- always followed soon by demand analysis. + ; (fn', spec_defns, body_uds1) <- specDefn rhs_env body_uds zapped_fn rhs ; let pairs = spec_defns ++ [(fn', rhs')] -- fn' mentions the spec_defns in its rules, @@ -1360,8 +1208,7 @@ type SpecInfo = ( [CoreRule] -- Specialisation rules specCalls mb_mod env existing_rules calls_for_me fn rhs -- The first case is the interesting one - | callSpecArity pis <= fn_arity -- See Note [Specialisation Must Preserve Sharing] - && notNull calls_for_me -- And there are some calls to specialise + | notNull calls_for_me -- And there are some calls to specialise && not (isNeverActive (idInlineActivation fn)) -- Don't specialise NOINLINE things -- See Note [Auto-specialisation and RULES] @@ -1381,27 +1228,22 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- pprTrace "specDefn: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) where - _trace_doc = sep [ ppr rhs_tyvars, ppr rhs_bndrs - , ppr (idInlineActivation fn) ] - - fn_type = idType fn - fn_arity = idArity fn - fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here - pis = fst $ splitPiTys fn_type - theta = getTheta pis - n_dicts = length theta - inl_prag = idInlinePragma fn - inl_act = inlinePragmaActivation inl_prag - is_local = isLocalId fn + _trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] + + fn_type = idType fn + fn_arity = idArity fn + fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here + inl_prag = idInlinePragma fn + inl_act = inlinePragmaActivation inl_prag + is_local = isLocalId fn -- Figure out whether the function has an INLINE pragma -- See Note [Inline specialisations] - (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs - -- See Note [Account for casts in binding] - rhs_tyvars = filter isTyVar rhs_bndrs + (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs + -- See Note [Account for casts in binding] - in_scope = GHC.Core.Subst.substInScope (se_subst env) + in_scope = Core.substInScope (se_subst env) already_covered :: DynFlags -> [CoreRule] -> [CoreExpr] -> Bool already_covered dflags new_rules args -- Note [Specialisations already covered] @@ -1416,38 +1258,43 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs spec_call :: SpecInfo -- Accumulating parameter -> CallInfo -- Call instance -> SpecM SpecInfo - spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) - (CI { ci_key = call_args, ci_arity = call_arity }) - = ASSERT(call_arity <= fn_arity) - - -- See Note [Specialising Calls] - do { (rhs_env2, unused_bndrs, rule_bndrs, rule_args, unspec_bndrs, dx_binds, spec_args) - <- specHeader env rhs_bndrs $ dropWhileEndLE isUnspecArg call_args - ; let rhs_body' = mkLams unused_bndrs rhs_body + spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) (CI { ci_key = call_args }) + = -- See Note [Specialising Calls] + do { ( useful, rhs_env2, leftover_bndrs + , rule_bndrs, rule_lhs_args + , spec_bndrs, dx_binds, spec_args) <- specHeader env rhs_bndrs call_args + ; dflags <- getDynFlags - ; if already_covered dflags rules_acc rule_args + ; if not useful -- No useful specialisation + || already_covered dflags rules_acc rule_lhs_args then return spec_acc else -- pprTrace "spec_call" (vcat [ ppr _call_info, ppr fn, ppr rhs_dict_ids -- , text "rhs_env2" <+> ppr (se_subst rhs_env2) -- , ppr dx_binds ]) $ - do - { -- Figure out the type of the specialised function - let body = mkLams unspec_bndrs rhs_body' - body_ty = substTy rhs_env2 $ exprType body - (lam_extra_args, app_args) -- See Note [Specialisations Must Be Lifted] - | isUnliftedType body_ty -- C.f. GHC.Core.Op.WorkWrap.Lib.mkWorkerArgs - , not (isJoinId fn) - = ([voidArgId], voidPrimId : unspec_bndrs) - | otherwise = ([], unspec_bndrs) - join_arity_change = length app_args - length rule_args + do { -- Run the specialiser on the specialised RHS + -- The "1" suffix is before we maybe add the void arg + ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs ++ leftover_bndrs) rhs_body + ; let spec_fn_ty1 = exprType spec_rhs1 + + -- Maybe add a void arg to the specialised function, + -- to avoid unlifted bindings + -- See Note [Specialisations Must Be Lifted] + -- C.f. GHC.Core.Op.WorkWrap.Lib.mkWorkerArgs + add_void_arg = isUnliftedType spec_fn_ty1 && not (isJoinId fn) + (spec_rhs, spec_fn_ty, rule_rhs_args) + | add_void_arg = ( Lam voidArgId spec_rhs1 + , mkVisFunTy voidPrimTy spec_fn_ty1 + , voidPrimId : spec_bndrs) + | otherwise = (spec_rhs1, spec_fn_ty1, spec_bndrs) + + arity_decr = count isValArg rule_lhs_args - count isId rule_rhs_args + join_arity_decr = length rule_lhs_args - length rule_rhs_args spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity + join_arity_change) + = Just (orig_join_arity - join_arity_decr) | otherwise = Nothing - ; (spec_rhs, rhs_uds) <- specExpr rhs_env2 (mkLams lam_extra_args body) - ; let spec_id_ty = exprType spec_rhs - ; spec_f <- newSpecIdSM fn spec_id_ty spec_join_arity + ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity ; this_mod <- getModule ; let -- The rule to put in the function's specialisation is: @@ -1475,13 +1322,12 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs inl_act -- Note [Auto-specialisation and RULES] (idName fn) rule_bndrs - rule_args - (mkVarApps (Var spec_f) app_args) + rule_lhs_args + (mkVarApps (Var spec_fn) rule_rhs_args) spec_rule = case isJoinId_maybe fn of - Just join_arity -> etaExpandToJoinPointRule join_arity - rule_wout_eta + Just join_arity -> etaExpandToJoinPointRule join_arity rule_wout_eta Nothing -> rule_wout_eta -- Add the { d1' = dx1; d2' = dx2 } usage stuff @@ -1500,7 +1346,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs = (inl_prag { inl_inline = NoUserInline }, noUnfolding) | otherwise - = (inl_prag, specUnfolding dflags unspec_bndrs spec_app n_dicts fn_unf) + = (inl_prag, specUnfolding dflags fn spec_bndrs spec_app arity_decr fn_unf) spec_app e = e `mkApps` spec_args @@ -1508,13 +1354,14 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- Adding arity information just propagates it a bit faster -- See Note [Arity decrease] in GHC.Core.Op.Simplify -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_f - spec_f_w_arity = spec_f `setIdArity` max 0 (fn_arity - n_dicts) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity - - _rule_trace_doc = vcat [ ppr spec_f, ppr fn_type, ppr spec_id_ty + -- So if f has INLINE[1] so does spec_fn + spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) + `setInlinePragma` spec_inl_prag + `setIdUnfolding` spec_unf + `asJoinId_maybe` spec_join_arity + + _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type + , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty , ppr rhs_bndrs, ppr call_args , ppr spec_rule ] @@ -1573,33 +1420,44 @@ preserve laziness. Note [Specialising Calls] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose we have a function: +Suppose we have a function with a complicated type: - f :: Int -> forall a b c. (Foo a, Foo c) => Bar -> Qux - f = \x -> /\ a b c -> \d1 d2 bar -> rhs + f :: forall a b c. Int -> Eq a => Show b => c -> Blah + f @a @b @c i dEqA dShowA x = blah and suppose it is called at: - f 7 @T1 @T2 @T3 dFooT1 dFooT3 bar + f 7 @T1 @T2 @T3 dEqT1 ($dfShow dShowT2) t3 -This call is described as a 'CallInfo' whose 'ci_key' is +This call is described as a 'CallInfo' whose 'ci_key' is: - [ UnspecArg, SpecType T1, UnspecType, SpecType T3, SpecDict dFooT1 - , SpecDict dFooT3, UnspecArg ] + [ SpecType T1, SpecType T2, UnspecType, UnspecArg, SpecDict dEqT1 + , SpecDict ($dfShow dShowT2), UnspecArg ] -Why are 'a' and 'c' identified as 'SpecType', while 'b' is 'UnspecType'? +Why are 'a' and 'b' identified as 'SpecType', while 'c' is 'UnspecType'? Because we must specialise the function on type variables that appear free in its *dictionary* arguments; but not on type variables that do not appear in any dictionaries, i.e. are fully polymorphic. Because this call has dictionaries applied, we'd like to specialise the call on any type argument that appears free in those dictionaries. -In this case, those are (a ~ T1, c ~ T3). +In this case, those are [a :-> T1, b :-> T2]. + +We also need to substitute the dictionary binders with their +specialised dictionaries. The simplest substitution would be +[dEqA :-> dEqT1, dShowA :-> $dfShow dShowT2], but this duplicates +work, since `$dfShow dShowT2` is a function application. Therefore, we +also want to *float the dictionary out* (via bindAuxiliaryDict), +creating a new dict binding + + dShow1 = $dfShow dShowT2 -As a result, we'd like to generate a function: +and the substitution [dEqA :-> dEqT1, dShowA :-> dShow1]. - $sf :: Int -> forall b. Bar -> Qux - $sf = SUBST[a->T1, c->T3, d1->d1', d2->d2'] (\x -> /\ b -> \bar -> rhs) +With the substitutions in hand, we can generate a specialised function: + + $sf :: forall c. Int -> c -> Blah + $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah) Note that the substitution is applied to the whole thing. This is convenient, but just slightly fragile. Notably: @@ -1607,20 +1465,71 @@ convenient, but just slightly fragile. Notably: We must construct a rewrite rule: - RULE "SPEC f @T1 _ @T3" - forall (x :: Int) (@b :: Type) (d1' :: Foo T1) (d2' :: Foo T3). - f x @T1 @b @T3 d1' d2' = $sf x @b + RULE "SPEC f @T1 @T2 _" + forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2). + f @T1 @T2 @c i d1 d2 = $sf @c i -In the rule, d1' and d2' are just wildcards, not used in the RHS. Note -additionally that 'bar' isn't captured by this rule --- we bind only +In the rule, d1 and d2 are just wildcards, not used in the RHS. Note +additionally that 'x' isn't captured by this rule --- we bind only enough etas in order to capture all of the *specialised* arguments. -Finally, we must also construct the usage-details +Note [Drop dead args from specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, it’s possible some of the arguments may +actually be dead. For example, consider: + + f :: forall a. () -> Show a => a -> String + f x y = show y ++ "!" + +We might generate the following CallInfo for `f @Int`: + + [SpecType Int, UnspecArg, SpecDict $dShowInt, UnspecArg] + +Normally we’d include both the x and y arguments in the +specialisation, since we’re not specialising on either of them. But +that’s silly, since x is actually unused! So we might as well drop it +in the specialisation: + + $sf :: Int -> String + $sf y = show y ++ "!" + + {-# RULE "SPEC f @Int" forall x. f @Int x $dShow = $sf #-} + +This doesn’t save us much, since the arg would be removed later by +worker/wrapper, anyway, but it’s easy to do. Note, however, that we +only drop dead arguments if: + + 1. We don’t specialise on them. + 2. They come before an argument we do specialise on. + +Doing the latter would require eta-expanding the RULE, which could +make it match less often, so it’s not worth it. Doing the former could +be more useful --- it would stop us from generating pointless +specialisations --- but it’s more involved to implement and unclear if +it actually provides much benefit in practice. - { d1' = dx1; d2' = dx2 } +Note [Zap occ info in rule binders] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we generate a specialisation RULE, we need to drop occurrence +info on the binders. If we don’t, things go wrong when we specialise a +function like + + f :: forall a. () -> Show a => a -> String + f x y = show y ++ "!" + +since we’ll generate a RULE like + + RULE "SPEC f @Int" forall x [Occ=Dead]. + f @Int x $dShow = $sf + +and Core Lint complains, even though x only appears on the LHS (due to +Note [Drop dead args from specialisations]). -where d1', d2' are cloned versions of d1,d2, with the type substitution -applied. These auxiliary bindings just avoid duplication of dx1, dx2. +Why is that a Lint error? Because the arguments on the LHS of a rule +are syntactically expressions, not patterns, so Lint treats the +appearance of x as a use rather than a binding. Fortunately, the +solution is simple: we just make sure to zap the occ info before +using ids as wildcard binders in a rule. Note [Account for casts in binding] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1675,56 +1584,6 @@ type correctness issue.) But specialisation rules are strictly for What this means is that a SPEC rules from auto-specialisation in module M will be used in other modules only if M.hi has been read for some other reason, which is actually pretty likely. --} - -bindAuxiliaryDicts - :: SpecEnv - -> [DictId] -> [CoreExpr] -- Original dict bndrs, and the witnessing expressions - -> [DictId] -- A cloned dict-id for each dict arg - -> (SpecEnv, -- Substitute for all orig_dicts - [DictBind], -- Auxiliary dict bindings - [CoreExpr]) -- Witnessing expressions (all trivial) --- Bind any dictionary arguments to fresh names, to preserve sharing -bindAuxiliaryDicts env@(SE { se_subst = subst, se_interesting = interesting }) - orig_dict_ids call_ds inst_dict_ids - = (env', dx_binds, spec_dict_args) - where - (dx_binds, spec_dict_args) = go call_ds inst_dict_ids - env' = env { se_subst = subst `GHC.Core.Subst.extendSubstList` - (orig_dict_ids `zip` spec_dict_args) - `GHC.Core.Subst.extendInScopeList` dx_ids - , se_interesting = interesting `unionVarSet` interesting_dicts } - - dx_ids = [dx_id | (NonRec dx_id _, _) <- dx_binds] - interesting_dicts = mkVarSet [ dx_id | (NonRec dx_id dx, _) <- dx_binds - , interestingDict env dx ] - -- See Note [Make the new dictionaries interesting] - - go :: [CoreExpr] -> [CoreBndr] -> ([DictBind], [CoreExpr]) - go [] _ = ([], []) - go (dx:dxs) (dx_id:dx_ids) - | exprIsTrivial dx = (dx_binds, dx : args) - | otherwise = (mkDB (NonRec dx_id dx) : dx_binds, Var dx_id : args) - where - (dx_binds, args) = go dxs dx_ids - -- In the first case extend the substitution but not bindings; - -- in the latter extend the bindings but not the substitution. - -- For the former, note that we bind the *original* dict in the substitution, - -- overriding any d->dx_id binding put there by substBndrs - go _ _ = pprPanic "bindAuxiliaryDicts" (ppr orig_dict_ids $$ ppr call_ds $$ ppr inst_dict_ids) - -{- -Note [Make the new dictionaries interesting] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Important! We're going to substitute dx_id1 for d -and we want it to look "interesting", else we won't gather *any* -consequential calls. E.g. - f d = ...g d.... -If we specialise f for a call (f (dfun dNumInt)), we'll get -a consequent call (g d') with an auxiliary definition - d' = df dNumInt -We want that consequent call to look interesting - Note [From non-recursive to recursive] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2060,15 +1919,297 @@ a complete solution; ignoring specialisation for now, INLINABLE functions don't get properly strictness analysed, for example. But it works well for examples involving specialisation, which is the dominant use of INLINABLE. See #4874. +-} - -************************************************************************ +{- ********************************************************************* * * -\subsubsection{UsageDetails and suchlike} + SpecArg, and specHeader * * -************************************************************************ +********************************************************************* -} + +-- | An argument that we might want to specialise. +-- See Note [Specialising Calls] for the nitty gritty details. +data SpecArg + = + -- | Type arguments that should be specialised, due to appearing + -- free in the type of a 'SpecDict'. + SpecType Type + + -- | Type arguments that should remain polymorphic. + | UnspecType + + -- | Dictionaries that should be specialised. mkCallUDs ensures + -- that only "interesting" dictionary arguments get a SpecDict; + -- see Note [Interesting dictionary arguments] + | SpecDict DictExpr + + -- | Value arguments that should not be specialised. + | UnspecArg + +instance Outputable SpecArg where + ppr (SpecType t) = text "SpecType" <+> ppr t + ppr UnspecType = text "UnspecType" + ppr (SpecDict d) = text "SpecDict" <+> ppr d + ppr UnspecArg = text "UnspecArg" + +specArgFreeVars :: SpecArg -> VarSet +specArgFreeVars (SpecType ty) = tyCoVarsOfType ty +specArgFreeVars (SpecDict dx) = exprFreeVars dx +specArgFreeVars UnspecType = emptyVarSet +specArgFreeVars UnspecArg = emptyVarSet + +isSpecDict :: SpecArg -> Bool +isSpecDict (SpecDict {}) = True +isSpecDict _ = False + +-- | Given binders from an original function 'f', and the 'SpecArg's +-- corresponding to its usage, compute everything necessary to build +-- a specialisation. +-- +-- We will use the running example from Note [Specialising Calls]: +-- +-- f :: forall a b c. Int -> Eq a => Show b => c -> Blah +-- f @a @b @c i dEqA dShowA x = blah +-- +-- Suppose we decide to specialise it at the following pattern: +-- +-- [ SpecType T1, SpecType T2, UnspecType, UnspecArg +-- , SpecDict dEqT1, SpecDict ($dfShow dShowT2), UnspecArg ] +-- +-- We'd eventually like to build the RULE +-- +-- RULE "SPEC f @T1 @T2 _" +-- forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2). +-- f @T1 @T2 @c i d1 d2 = $sf @c i +-- +-- and the specialisation '$sf' +-- +-- $sf :: forall c. Int -> c -> Blah +-- $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah) +-- +-- where dShow1 is a floated binding created by bindAuxiliaryDict. +-- +-- The cases for 'specHeader' below are presented in the same order as this +-- running example. The result of 'specHeader' for this example is as follows: +-- +-- ( -- Returned arguments +-- env + [a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] +-- , [x] +-- +-- -- RULE helpers +-- , [c, i, d1, d2] +-- , [T1, T2, c, i, d1, d2] +-- +-- -- Specialised function helpers +-- , [c, i, x] +-- , [dShow1 = $dfShow dShowT2] +-- , [T1, T2, dEqT1, dShow1] +-- ) +specHeader + :: SpecEnv + -> [InBndr] -- The binders from the original function 'f' + -> [SpecArg] -- From the CallInfo + -> SpecM ( Bool -- True <=> some useful specialisation happened + -- Not the same as any (isSpecDict args) because + -- the args might be longer than bndrs + + -- Returned arguments + , SpecEnv -- Substitution to apply to the body of 'f' + , [OutBndr] -- Leftover binders from the original function 'f' + -- that don’t have a corresponding SpecArg + + -- RULE helpers + , [OutBndr] -- Binders for the RULE + , [CoreArg] -- Args for the LHS of the rule + + -- Specialised function helpers + , [OutBndr] -- Binders for $sf + , [DictBind] -- Auxiliary dictionary bindings + , [OutExpr] -- Specialised arguments for unfolding + ) + +-- We want to specialise on type 'T1', and so we must construct a substitution +-- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding +-- details. +specHeader env (bndr : bndrs) (SpecType t : args) + = do { let env' = extendTvSubstList env [(bndr, t)] + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , rule_bs + , Type t : rule_es + , bs' + , dx + , Type t : spec_args + ) + } + +-- Next we have a type that we don't want to specialise. We need to perform +-- a substitution on it (in case the type refers to 'a'). Additionally, we need +-- to produce a binder, LHS argument and RHS argument for the resulting rule, +-- /and/ a binder for the specialised body. +specHeader env (bndr : bndrs) (UnspecType : args) + = do { let (env', bndr') = substBndr env bndr + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , bndr' : rule_bs + , varToCoreExpr bndr' : rule_es + , bndr' : bs' + , dx + , varToCoreExpr bndr' : spec_args + ) + } + +-- Next we want to specialise the 'Eq a' dict away. We need to construct +-- a wildcard binder to match the dictionary (See Note [Specialising Calls] for +-- the nitty-gritty), as a LHS rule and unfolding details. +specHeader env (bndr : bndrs) (SpecDict d : args) + = do { bndr' <- newDictBndr env bndr -- See Note [Zap occ info in rule binders] + ; let (env', dx_bind, spec_dict) = bindAuxiliaryDict env bndr bndr' d + ; (_, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( True -- Ha! A useful specialisation! + , env'' + , leftover_bndrs + -- See Note [Evidence foralls] + , exprFreeIdsList (varToCoreExpr bndr') ++ rule_bs + , varToCoreExpr bndr' : rule_es + , bs' + , maybeToList dx_bind ++ dx + , spec_dict : spec_args + ) + } + +-- Finally, we have the unspecialised argument 'i'. We need to produce +-- a binder, LHS and RHS argument for the RULE, and a binder for the +-- specialised body. +-- +-- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is +-- why 'i' doesn't appear in our RULE above. But we have no guarantee that +-- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so +-- this case must be here. +specHeader env (bndr : bndrs) (UnspecArg : args) + = do { -- see Note [Zap occ info in rule binders] + let (env', bndr') = substBndr env (zapIdOccInfo bndr) + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , bndr' : rule_bs + , varToCoreExpr bndr' : rule_es + , if isDeadBinder bndr + then bs' -- see Note [Drop dead args from specialisations] + else bndr' : bs' + , dx + , varToCoreExpr bndr' : spec_args + ) + } + +-- If we run out of binders, stop immediately +-- See Note [Specialisation Must Preserve Sharing] +specHeader env [] _ = pure (False, env, [], [], [], [], [], []) + +-- Return all remaining binders from the original function. These have the +-- invariant that they should all correspond to unspecialised arguments, so +-- it's safe to stop processing at this point. +specHeader env bndrs [] + = pure (False, env', bndrs', [], [], [], [], []) + where + (env', bndrs') = substBndrs env bndrs + + +-- | Binds a dictionary argument to a fresh name, to preserve sharing +bindAuxiliaryDict + :: SpecEnv + -> InId -> OutId -> OutExpr -- Original dict binder, and the witnessing expression + -> ( SpecEnv -- Substitute for orig_dict_id + , Maybe DictBind -- Auxiliary dict binding, if any + , OutExpr) -- Witnessing expression (always trivial) +bindAuxiliaryDict env@(SE { se_subst = subst, se_interesting = interesting }) + orig_dict_id fresh_dict_id dict_expr + + -- If the dictionary argument is trivial, + -- don’t bother creating a new dict binding; just substitute + | Just dict_id <- getIdFromTrivialExpr_maybe dict_expr + = let env' = env { se_subst = Core.extendSubst subst orig_dict_id dict_expr + `Core.extendInScope` dict_id + -- See Note [Keep the old dictionaries interesting] + , se_interesting = interesting `extendVarSet` dict_id } + in (env', Nothing, dict_expr) + + | otherwise -- Non-trivial dictionary arg; make an auxiliary binding + = let dict_bind = mkDB (NonRec fresh_dict_id dict_expr) + env' = env { se_subst = Core.extendSubst subst orig_dict_id (Var fresh_dict_id) + `Core.extendInScope` fresh_dict_id + -- See Note [Make the new dictionaries interesting] + , se_interesting = interesting `extendVarSet` fresh_dict_id } + in (env', Just dict_bind, Var fresh_dict_id) + +{- +Note [Make the new dictionaries interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Important! We're going to substitute dx_id1 for d +and we want it to look "interesting", else we won't gather *any* +consequential calls. E.g. + f d = ...g d.... +If we specialise f for a call (f (dfun dNumInt)), we'll get +a consequent call (g d') with an auxiliary definition + d' = df dNumInt +We want that consequent call to look interesting + +Note [Keep the old dictionaries interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In bindAuxiliaryDict, we don’t bother creating a new dict binding if +the dict expression is trivial. For example, if we have + + f = \ @m1 (d1 :: Monad m1) -> ... + +and we specialize it at the pattern + + [SpecType IO, SpecArg $dMonadIO] + +it would be silly to create a new binding for $dMonadIO; it’s already +a binding! So we just extend the substitution directly: + + m1 :-> IO + d1 :-> $dMonadIO + +But this creates a new subtlety: the dict expression might be a dict +binding we floated out while specializing another function. For +example, we might have + + d2 = $p1Monad $dMonadIO -- floated out by bindAuxiliaryDict + $sg = h @IO d2 + h = \ @m2 (d2 :: Applicative m2) -> ... + +and end up specializing h at the following pattern: + + [SpecType IO, SpecArg d2] + +When we created the d2 binding in the first place, we locally marked +it as interesting while specializing g as described above by +Note [Make the new dictionaries interesting]. But when we go to +specialize h, it isn’t in the SpecEnv anymore, so we’ve lost the +knowledge that we should specialize on it. + +To fix this, we have to explicitly add d2 *back* to the interesting +set. That way, it will still be considered interesting while +specializing the body of h. See !2913. -} + +{- ********************************************************************* +* * + UsageDetails and suchlike +* * +********************************************************************* -} + data UsageDetails = MkUD { ud_binds :: !(Bag DictBind), @@ -2138,8 +2279,6 @@ data CallInfoSet = CIS Id (Bag CallInfo) data CallInfo = CI { ci_key :: [SpecArg] -- All arguments - , ci_arity :: Int -- The number of variables necessary to bind - -- all of the specialised arguments , ci_fvs :: VarSet -- Free vars of the ci_key -- call (including tyvars) -- [*not* include the main id itself, of course] @@ -2185,12 +2324,6 @@ callInfoFVs :: CallInfoSet -> VarSet callInfoFVs (CIS _ call_info) = foldr (\(CI { ci_fvs = fv }) vs -> unionVarSet fv vs) emptyVarSet call_info -computeArity :: [SpecArg] -> Int -computeArity = length . filter isValueArg . dropWhileEndLE isUnspecArg - -callSpecArity :: [TyCoBinder] -> Int -callSpecArity = length . filter (not . isNamedBinder) . dropWhileEndLE isVisibleBinder - getTheta :: [TyCoBinder] -> [PredType] getTheta = fmap tyBinderType . filter isInvisibleBinder . filter (not . isNamedBinder) @@ -2201,13 +2334,9 @@ singleCall id args = MkUD {ud_binds = emptyBag, ud_calls = unitDVarEnv id $ CIS id $ unitBag (CI { ci_key = args -- used to be tys - , ci_arity = computeArity args , ci_fvs = call_fvs }) } where - tys = getSpecTypes args - dicts = getSpecDicts args - call_fvs = exprsFreeVars dicts `unionVarSet` tys_fvs - tys_fvs = tyCoVarsOfTypes tys + call_fvs = foldr (unionVarSet . specArgFreeVars) emptyVarSet args -- The type args (tys) are guaranteed to be part of the dictionary -- types, because they are just the constrained types, -- and the dictionary is therefore sure to be bound @@ -2226,42 +2355,47 @@ mkCallUDs env f args res = mkCallUDs' env f args mkCallUDs' env f args - | not (want_calls_for f) -- Imported from elsewhere - || null theta -- Not overloaded - = emptyUDs - - | not (all type_determines_value theta) - || not (computeArity ci_key <= idArity f) - || not (length dicts == length theta) - || not (any (interestingDict env) dicts) -- Note [Interesting dictionary arguments] - -- See also Note [Specialisations already covered] + | not (want_calls_for f) -- Imported from elsewhere + || null ci_key -- No useful specialisation + -- See also Note [Specialisations already covered] = -- pprTrace "mkCallUDs: discarding" _trace_doc - emptyUDs -- Not overloaded, or no specialisation wanted + emptyUDs | otherwise = -- pprTrace "mkCallUDs: keeping" _trace_doc singleCall f ci_key where - _trace_doc = vcat [ppr f, ppr args, ppr (map (interestingDict env) dicts)] + _trace_doc = vcat [ppr f, ppr args, ppr ci_key] pis = fst $ splitPiTys $ idType f - theta = getTheta pis - constrained_tyvars = tyCoVarsOfTypes theta + constrained_tyvars = tyCoVarsOfTypes $ getTheta pis ci_key :: [SpecArg] - ci_key = fmap (\(t, a) -> - case t of - Named (binderVar -> tyVar) - | tyVar `elemVarSet` constrained_tyvars - -> case a of - Type ty -> SpecType ty - _ -> pprPanic "ci_key" $ ppr a - | otherwise - -> UnspecType - Anon InvisArg _ -> SpecDict a - Anon VisArg _ -> UnspecArg - ) $ zip pis args - - dicts = getSpecDicts ci_key + ci_key = dropWhileEndLE (not . isSpecDict) $ + zipWith mk_spec_arg args pis + -- Drop trailing args until we get to a SpecDict + -- In this way the RULE has as few args as possible, + -- which broadens its applicability, since rules only + -- fire when saturated + + mk_spec_arg :: CoreExpr -> TyCoBinder -> SpecArg + mk_spec_arg arg (Named bndr) + | binderVar bndr `elemVarSet` constrained_tyvars + = case arg of + Type ty -> SpecType ty + _ -> pprPanic "ci_key" $ ppr arg + | otherwise = UnspecType + + -- For "InvisArg", which are the type-class dictionaries, + -- we decide on a case by case basis if we want to specialise + -- on this argument; if so, SpecDict, if not UnspecArg + mk_spec_arg arg (Anon InvisArg pred) + | type_determines_value pred + , interestingDict env arg -- Note [Interesting dictionary arguments] + = SpecDict arg + | otherwise = UnspecArg + + mk_spec_arg _ (Anon VisArg _) + = UnspecArg want_calls_for f = isLocalId f || isJust (maybeUnfoldingTemplate (realIdUnfolding f)) -- For imported things, we gather call instances if @@ -2281,12 +2415,18 @@ mkCallUDs' env f args {- Note [Type determines value] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Only specialise if all overloading is on non-IP *class* params, -because these are the ones whose *type* determines their *value*. In -parrticular, with implicit params, the type args *don't* say what the -value of the implicit param is! See #7101 - -However, consider +Only specialise on non-IP *class* params, because these are the ones +whose *type* determines their *value*. In particular, with implicit +params, the type args *don't* say what the value of the implicit param +is! See #7101. + +So we treat implicit params just like ordinary arguments for the +purposes of specialisation. Note that we still want to specialise +functions with implicit params if they have *other* dicts which are +class params; see #17930. + +One apparent additional complexity involves type families. For +example, consider type family D (v::*->*) :: Constraint type instance D [] = () f :: D v => v Char -> Int @@ -2297,8 +2437,7 @@ and it's good to specialise f at this dictionary. So the question is: can an implicit parameter "hide inside" a type-family constraint like (D a). Well, no. We don't allow type instance D Maybe = ?x:Int -Hence the IrredPred case in type_determines_value. -See #7785. +Hence the IrredPred case in type_determines_value. See #7785. Note [Interesting dictionary arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2591,20 +2730,20 @@ mapAndCombineSM f (x:xs) = do (y, uds1) <- f x extendTvSubstList :: SpecEnv -> [(TyVar,Type)] -> SpecEnv extendTvSubstList env tv_binds - = env { se_subst = GHC.Core.Subst.extendTvSubstList (se_subst env) tv_binds } + = env { se_subst = Core.extendTvSubstList (se_subst env) tv_binds } substTy :: SpecEnv -> Type -> Type -substTy env ty = GHC.Core.Subst.substTy (se_subst env) ty +substTy env ty = Core.substTy (se_subst env) ty substCo :: SpecEnv -> Coercion -> Coercion -substCo env co = GHC.Core.Subst.substCo (se_subst env) co +substCo env co = Core.substCo (se_subst env) co substBndr :: SpecEnv -> CoreBndr -> (SpecEnv, CoreBndr) -substBndr env bs = case GHC.Core.Subst.substBndr (se_subst env) bs of +substBndr env bs = case Core.substBndr (se_subst env) bs of (subst', bs') -> (env { se_subst = subst' }, bs') substBndrs :: SpecEnv -> [CoreBndr] -> (SpecEnv, [CoreBndr]) -substBndrs env bs = case GHC.Core.Subst.substBndrs (se_subst env) bs of +substBndrs env bs = case Core.substBndrs (se_subst env) bs of (subst', bs') -> (env { se_subst = subst' }, bs') cloneBindSM :: SpecEnv -> CoreBind -> SpecM (SpecEnv, SpecEnv, CoreBind) @@ -2612,7 +2751,7 @@ cloneBindSM :: SpecEnv -> CoreBind -> SpecM (SpecEnv, SpecEnv, CoreBind) -- Return the substitution to use for RHSs, and the one to use for the body cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (NonRec bndr rhs) = do { us <- getUniqueSupplyM - ; let (subst', bndr') = GHC.Core.Subst.cloneIdBndr subst us bndr + ; let (subst', bndr') = Core.cloneIdBndr subst us bndr interesting' | interestingDict env rhs = interesting `extendVarSet` bndr' | otherwise = interesting @@ -2621,7 +2760,7 @@ cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (NonRec cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (Rec pairs) = do { us <- getUniqueSupplyM - ; let (subst', bndrs') = GHC.Core.Subst.cloneRecIdBndrs subst us (map fst pairs) + ; let (subst', bndrs') = Core.cloneRecIdBndrs subst us (map fst pairs) env' = env { se_subst = subst' , se_interesting = interesting `extendVarSetList` [ v | (v,r) <- pairs, interestingDict env r ] } @@ -2631,9 +2770,9 @@ newDictBndr :: SpecEnv -> CoreBndr -> SpecM CoreBndr -- Make up completely fresh binders for the dictionaries -- Their bindings are going to float outwards newDictBndr env b = do { uniq <- getUniqueM - ; let n = idName b - ty' = substTy env (idType b) - ; return (mkUserLocal (nameOccName n) uniq ty' (getSrcSpan n)) } + ; let n = idName b + ty' = substTy env (idType b) + ; return (mkUserLocal (nameOccName n) uniq ty' (getSrcSpan n)) } newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id -- Give the new Id a similar occurrence name to the old one ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -17,7 +17,7 @@ module GHC.Core.Subst ( deShadowBinds, substSpec, substRulesForImportedIds, substTy, substCo, substExpr, substExprSC, substBind, substBindSC, substUnfolding, substUnfoldingSC, - lookupIdSubst, lookupTCvSubst, substIdOcc, + lookupIdSubst, lookupTCvSubst, substIdType, substIdOcc, substTickish, substDVarSet, substIdInfo, -- ** Operations on substitutions @@ -756,4 +756,3 @@ analyser, so it's possible that the worker is not even in scope any more. In all all these cases we simply drop the special case, returning to InlVanilla. The WARN is just so I can see if it happens a lot. -} - ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -173,15 +173,16 @@ mkInlinableUnfolding dflags expr where expr' = simpleOptExpr dflags expr -specUnfolding :: DynFlags -> [Var] -> (CoreExpr -> CoreExpr) -> Arity +specUnfolding :: DynFlags -> Id -> [Var] -> (CoreExpr -> CoreExpr) -> Arity -> Unfolding -> Unfolding -- See Note [Specialising unfoldings] -- specUnfolding spec_bndrs spec_app arity_decrease unf -- = \spec_bndrs. spec_app( unf ) -- -specUnfolding dflags spec_bndrs spec_app arity_decrease +specUnfolding dflags fn spec_bndrs spec_app arity_decrease df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args }) - = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs, ppr df ) + = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs + , ppr df $$ ppr spec_bndrs $$ ppr (spec_app (Var fn)) $$ ppr arity_decrease ) mkDFunUnfolding spec_bndrs con (map spec_arg args) -- There is a hard-to-check assumption here that the spec_app has -- enough applications to exactly saturate the old_bndrs @@ -195,7 +196,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr -specUnfolding dflags spec_bndrs spec_app arity_decrease +specUnfolding dflags _ spec_bndrs spec_app arity_decrease (CoreUnfolding { uf_src = src, uf_tmpl = tmpl , uf_is_top = top_lvl , uf_guidance = old_guidance }) @@ -212,7 +213,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease in mkCoreUnfolding src top_lvl new_tmpl guidance -specUnfolding _ _ _ _ _ = noUnfolding +specUnfolding _ _ _ _ _ _ = noUnfolding {- Note [Specialising unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -701,7 +701,7 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl)) { this_mod <- getModule ; let fn_unf = realIdUnfolding poly_id - spec_unf = specUnfolding dflags spec_bndrs core_app arity_decrease fn_unf + spec_unf = specUnfolding dflags poly_id spec_bndrs core_app arity_decrease fn_unf spec_id = mkLocalId spec_name spec_ty `setInlinePragma` inl_prag `setIdUnfolding` spec_unf ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -92,6 +92,12 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) @@ -117,18 +123,19 @@ Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -2,6 +2,11 @@ TOP=../../.. include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk +T17966: + $(RM) -f T17966.o T17966.hi + - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-spec T17966.hs 2> /dev/null | grep 'SPEC' + # Expecting a SPEC rule for $cm + T17409: $(RM) -f T17409.o T17409.hi - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -dverbose-core2core -dsuppress-uniques T17409.hs 2> /dev/null | grep '\' ===================================== testsuite/tests/simplCore/should_compile/T17810.hs ===================================== @@ -0,0 +1,7 @@ +module T17801 where + +import Control.Monad.Except +import T17810a + +f :: ExceptT e (TCMT IO) () +f = liftReduce ===================================== testsuite/tests/simplCore/should_compile/T17810a.hs ===================================== @@ -0,0 +1,27 @@ +module T17810a where + +import Control.Monad.Except + +class Monad m => ReadTCState m where + locallyTCState :: m () + liftReduce :: m () + +instance ReadTCState m => ReadTCState (ExceptT err m) where + locallyTCState = undefined + liftReduce = lift liftReduce + +instance MonadIO m => ReadTCState (TCMT m) where + locallyTCState = (undefined <$> liftReduce) <* TCM (\_ -> return ()) + liftReduce = undefined + +newtype TCMT m a = TCM { unTCM :: () -> m a } + +instance MonadIO m => Functor (TCMT m) where + fmap f (TCM m) = TCM $ \r -> liftM f (m r ) + +instance MonadIO m => Applicative (TCMT m) where + pure x = TCM (\_ -> return x) + (<*>) (TCM mf) (TCM m) = TCM $ \r -> ap (mf r) (m r) + +instance MonadIO m => Monad (TCMT m) where + (>>=) (TCM m) k = TCM $ \r -> m r >>= \x -> unTCM (k x) r ===================================== testsuite/tests/simplCore/should_compile/T17930.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE ImplicitParams #-} +module T17930 where + +foo :: (?b :: Bool, Show a) => a -> String +foo x | ?b = show x ++ "!" + | otherwise = show x ++ "." +{-# INLINABLE[0] foo #-} + +str :: String +str = let ?b = True in foo "Hello" ===================================== testsuite/tests/simplCore/should_compile/T17930.stderr ===================================== @@ -0,0 +1,2 @@ +$sfoo :: (?b::Bool) => [Char] -> [Char] +$sfoo ===================================== testsuite/tests/simplCore/should_compile/T17966.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +-- The issue here is whether $cm gets a specialiation +-- See #17966 + +module T17966 where + +class C a b where + m :: Show c => a -> b -> c -> String + +instance Show b => C Bool b where + m a b c = show a ++ show b ++ show c + {-# INLINABLE [0] m #-} + +f :: (C a b, Show c) => a -> b -> c -> String +f a b c = m a b c ++ "!" +{-# INLINABLE [0] f #-} + +x :: String +x = f True () (Just 42) ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -0,0 +1,4 @@ + RULES: "SPEC $cm @()" [0] + RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] +"SPEC/T17966 $fShowMaybe_$cshowList @Integer" +"SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -319,3 +319,10 @@ test('T17787', [ grep_errmsg(r'foo') ], compile, ['-ddump-simpl -dsuppress-uniq test('T17901', normal, makefile_test, ['T17901']) +test('T17930', [ grep_errmsg(r'^\$sfoo') ], compile, ['-O -ddump-spec -dsuppress-uniques -dsuppress-idinfo']) +test('spec004', [ grep_errmsg(r'\$sfoo') ], compile, ['-O -ddump-spec -dsuppress-uniques']) +test('T17966', + normal, + makefile_test, ['T17966']) +# NB: T17810: -fspecialise-aggressively +test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) ===================================== testsuite/tests/simplCore/should_compile/spec004.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE RankNTypes #-} + +-- Dead arguments should be dropped in specialisations. See !2913. + +module ShouldCompile where + +foo :: () -> Show a => a -> String +foo _x y = show y ++ "!" +{-# NOINLINE[0] foo #-} + +bar :: String +bar = foo () (42 :: Int) ===================================== testsuite/tests/simplCore/should_compile/spec004.stderr ===================================== @@ -0,0 +1,84 @@ + +==================== Specialise ==================== +Result size of Specialise + = {terms: 53, types: 46, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 14, types: 12, coercions: 0, joins: 0/0} +$sfoo [InlPrag=NOINLINE[0]] :: Int -> [Char] +[LclId] +$sfoo + = \ (y :: Int) -> + GHC.Base.build + @Char + (\ (@b) (c [OS=OneShot] :: Char -> b -> b) (n [OS=OneShot] :: b) -> + GHC.Base.foldr + @Char + @b + c + (GHC.CString.unpackFoldrCString# @b "!"# c n) + (show @Int GHC.Show.$fShowInt y)) + +-- RHS size: {terms: 17, types: 17, coercions: 0, joins: 0/0} +foo [InlPrag=NOINLINE[0]] :: forall a. () -> Show a => a -> String +[LclIdX, + Arity=3, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 30 0] 150 40}, + RULES: "SPEC foo @Int" [0] + forall (dk :: ()) ($dShow :: Show Int). foo @Int dk $dShow = $sfoo] +foo + = \ (@a) _ [Occ=Dead] ($dShow :: Show a) (y :: a) -> + GHC.Base.build + @Char + (\ (@b) (c [OS=OneShot] :: Char -> b -> b) (n [OS=OneShot] :: b) -> + GHC.Base.foldr + @Char + @b + c + (GHC.CString.unpackFoldrCString# @b "!"# c n) + (show @a $dShow y)) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 50 0}] +$trModule = "ShouldCompile"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +ShouldCompile.$trModule :: GHC.Types.Module +[LclIdX, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +ShouldCompile.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +bar :: String +[LclIdX, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 0}] +bar = foo @Int GHC.Tuple.() GHC.Show.$fShowInt (GHC.Types.I# 42#) + + + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4291bddaea3148908c55f235ee8978e1d9aa6f20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4291bddaea3148908c55f235ee8978e1d9aa6f20 You're receiving 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 3 11:40:29 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 03 Apr 2020 07:40:29 -0400 Subject: [Git][ghc/ghc][wip/T17151] 11 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e8720adc4f5d_616713279f6c2742145@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17151 at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 1468aa74 by Simon Peyton Jones at 2020-04-03T12:10:48+01:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - 8927189a by Simon Peyton Jones at 2020-04-03T12:12:56+01:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Iface/Ext/Debug.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/414790d53a5e5cded062b31eb07dd3860b371396...8927189a1abc3f107bc2c1e06df3dbe7d5e2bd98 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/414790d53a5e5cded062b31eb07dd3860b371396...8927189a1abc3f107bc2c1e06df3dbe7d5e2bd98 You're receiving 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 3 12:14:08 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 03 Apr 2020 08:14:08 -0400 Subject: [Git][ghc/ghc][wip/T17151] 2 commits: Fix an tricky specialiser loop Message-ID: <5e872890e264c_61676653460274997f@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17151 at Glasgow Haskell Compiler / GHC Commits: c8a02a02 by Simon Peyton Jones at 2020-04-03T13:13:57+01:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - fd12d84e by Simon Peyton Jones at 2020-04-03T13:13:57+01:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - 5 changed files: - compiler/GHC/Core/Op/Specialise.hs - + testsuite/tests/simplCore/should_run/T17151.hs - + testsuite/tests/simplCore/should_run/T17151.stdout - + testsuite/tests/simplCore/should_run/T17151a.hs - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -589,19 +589,11 @@ specProgram guts@(ModGuts { mg_module = this_mod -- Specialise the bindings of this module ; (binds', uds) <- runSpecM dflags this_mod (go binds) - -- Specialise imported functions - ; hpt_rules <- getRuleBase - ; let rule_base = extendRuleBaseList hpt_rules local_rules - ; (new_rules, spec_binds) <- specImports dflags this_mod top_env emptyVarSet - [] rule_base uds - - ; let final_binds - | null spec_binds = binds' - | otherwise = Rec (flattenBinds spec_binds) : binds' - -- Note [Glom the bindings if imported functions are specialised] + ; (spec_rules, spec_binds) <- specImports dflags this_mod top_env + local_rules uds - ; return (guts { mg_binds = final_binds - , mg_rules = new_rules ++ local_rules }) } + ; return (guts { mg_binds = spec_binds ++ binds' + , mg_rules = spec_rules ++ local_rules }) } where -- We need to start with a Subst that knows all the things -- that are in scope, so that the substitution engine doesn't @@ -645,72 +637,93 @@ See #10491 * * ********************************************************************* -} --- | Specialise a set of calls to imported bindings -specImports :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these ones - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module and the home package - -- (but not external packages, which can change) - -> UsageDetails -- Calls for imported things, and floating bindings - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings - -- See Note [Wrapping bindings returned by specImports] -specImports dflags this_mod top_env done callers rule_base +specImports :: DynFlags -> Module -> SpecEnv + -> [CoreRule] + -> UsageDetails + -> CoreM ([CoreRule], [CoreBind]) +specImports dflags this_mod top_env local_rules (MkUD { ud_binds = dict_binds, ud_calls = calls }) - -- See Note [Disabling cross-module specialisation] | not $ gopt Opt_CrossModuleSpecialise dflags - = return ([], []) + -- See Note [Disabling cross-module specialisation] + = return ([], wrapDictBinds dict_binds []) | otherwise - = do { let import_calls = dVarEnvElts calls - ; (rules, spec_binds) <- go rule_base import_calls + = do { hpt_rules <- getRuleBase + ; let rule_base = extendRuleBaseList hpt_rules local_rules + + ; (spec_rules, spec_binds) <- spec_imports dflags this_mod top_env + [] rule_base + dict_binds calls -- Don't forget to wrap the specialized bindings with -- bindings for the needed dictionaries. -- See Note [Wrap bindings returned by specImports] - ; let spec_binds' = wrapDictBinds dict_binds spec_binds + -- and Note [Glom the bindings if imported functions are specialised] + ; let final_binds + | null spec_binds = wrapDictBinds dict_binds [] + | otherwise = [Rec $ flattenBinds $ + wrapDictBinds dict_binds spec_binds] + + ; return (spec_rules, final_binds) + } + +-- | Specialise a set of calls to imported bindings +spec_imports :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module and the home package + -- (but not external packages, which can change) + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallDetails -- Calls for imported things + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_imports dflags this_mod top_env + callers rule_base dict_binds calls + = do { let import_calls = dVarEnvElts calls + -- ; debugTraceMsg (text "specImports {" <+> + -- vcat [ text "calls:" <+> ppr import_calls + -- , text "dict_binds:" <+> ppr dict_binds ]) + ; (rules, spec_binds) <- go rule_base import_calls + -- ; debugTraceMsg (text "End specImports }" <+> ppr import_calls) - ; return (rules, spec_binds') } + ; return (rules, spec_binds) } where go :: RuleBase -> [CallInfoSet] -> CoreM ([CoreRule], [CoreBind]) go _ [] = return ([], []) - go rb (cis@(CIS fn _) : other_calls) - = do { let ok_calls = filterCalls cis dict_binds - -- Drop calls that (directly or indirectly) refer to fn - -- See Note [Avoiding loops] --- ; debugTraceMsg (text "specImport" <+> vcat [ ppr fn --- , text "calls" <+> ppr cis --- , text "ud_binds =" <+> ppr dict_binds --- , text "dump set =" <+> ppr dump_set --- , text "filtered calls =" <+> ppr ok_calls ]) - ; (rules1, spec_binds1) <- specImport dflags this_mod top_env - done callers rb fn ok_calls + go rb (cis : other_calls) + = do { -- debugTraceMsg (text "specImport {" <+> ppr cis) + ; (rules1, spec_binds1) <- spec_import dflags this_mod top_env + callers rb dict_binds cis + -- ; debugTraceMsg (text "specImport }" <+> ppr cis) ; (rules2, spec_binds2) <- go (extendRuleBaseList rb rules1) other_calls ; return (rules1 ++ rules2, spec_binds1 ++ spec_binds2) } -specImport :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module - -> Id -> [CallInfo] -- Imported function and calls for it - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings -specImport dflags this_mod top_env done callers rb fn calls_for_fn - | fn `elemVarSet` done +spec_import :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallInfoSet -- Imported function and calls for it + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_import dflags this_mod top_env callers + rb dict_binds cis@(CIS fn _) + | isIn "specImport" fn callers = return ([], []) -- No warning. This actually happens all the time -- when specialising a recursive function, because -- the RHS of the specialised function contains a recursive -- call to the original function - | null calls_for_fn -- We filtered out all the calls in deleteCallsMentioning - = return ([], []) + | null good_calls + = do { -- debugTraceMsg (text "specImport:no valid calls") + ; return ([], []) } | wantSpecImport dflags unfolding , Just rhs <- maybeUnfoldingTemplate unfolding @@ -723,32 +736,37 @@ specImport dflags this_mod top_env done callers rb fn calls_for_fn ; let full_rb = unionRuleBase rb (eps_rule_base eps) rules_for_fn = getRules (RuleEnv full_rb vis_orphs) fn - ; (rules1, spec_pairs, uds) - <- -- pprTrace "specImport1" (vcat [ppr fn, ppr calls_for_fn, ppr rhs]) $ - runSpecM dflags this_mod $ - specCalls (Just this_mod) top_env rules_for_fn calls_for_fn fn rhs + ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls }) + <- do { -- debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls, ppr rhs]) + ; runSpecM dflags this_mod $ + specCalls (Just this_mod) top_env rules_for_fn good_calls fn rhs } ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs] -- After the rules kick in we may get recursion, but -- we rely on a global GlomBinds to sort that out later -- See Note [Glom the bindings if imported functions are specialised] -- Now specialise any cascaded calls - ; (rules2, spec_binds2) <- -- pprTrace "specImport 2" (ppr fn $$ ppr rules1 $$ ppr spec_binds1) $ - specImports dflags this_mod top_env - (extendVarSet done fn) - (fn:callers) - (extendRuleBaseList rb rules1) - uds + -- ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) + ; (rules2, spec_binds2) <- spec_imports dflags this_mod top_env + (fn:callers) + (extendRuleBaseList rb rules1) + (dict_binds `unionBags` dict_binds1) + new_calls - ; let final_binds = spec_binds2 ++ spec_binds1 + ; let final_binds = wrapDictBinds dict_binds1 $ + spec_binds2 ++ spec_binds1 ; return (rules2 ++ rules1, final_binds) } - | otherwise = do { tryWarnMissingSpecs dflags callers fn calls_for_fn - ; return ([], [])} + | otherwise + = do { tryWarnMissingSpecs dflags callers fn good_calls + ; return ([], [])} where unfolding = realIdUnfolding fn -- We want to see the unfolding even for loop breakers + good_calls = filterCalls cis dict_binds + -- SUPER IMPORTANT! Drop calls that (directly or indirectly) refer to fn + -- See Note [Avoiding loops in specImports] -- | Returns whether or not to show a missed-spec warning. -- If -Wall-missed-specializations is on, show the warning. @@ -790,8 +808,114 @@ wantSpecImport dflags unf -- inside it that we want to specialise | otherwise -> False -- Stable, not INLINE, hence INLINABLE -{- Note [Warning about missed specialisations] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Avoiding loops in specImports] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We must take great care when specialising instance declarations +(functions like $fOrdList) lest we accidentally build a recursive +dictionary. See Note [Avoiding loops]. + +The basic strategy of Note [Avoiding loops] is to use filterCalls +to discard loopy specialisations. But to do that we must ensure +that the in-scope dict-binds (passed to filterCalls) contains +all the needed dictionary bindings. In particular, in the recursive +call to spec_imorpts in spec_import, we must include the dict-binds +from the parent. Lacking this caused #17151, a really nasty bug. + +Here is what happened. +* Class struture: + Source is a superclass of Mut + Index is a superclass of Source + +* We started with these dict binds + dSource = $fSourcePix @Int $fIndexInt + dIndex = sc_sel dSource + dMut = $fMutPix @Int dIndex + and these calls to specialise + $fMutPix @Int dIndex + $fSourcePix @Int $fIndexInt + +* We specialised the call ($fMutPix @Int dIndex) + ==> new call ($fSourcePix @Int dIndex) + (because Source is a superclass of Mut) + +* We specialised ($fSourcePix @Int dIndex) + ==> produces specialised dict $s$fSourcePix, + a record with dIndex as a field + plus RULE forall d. ($fSourcePix @Int d) = $s$fSourcePix + *** This is the bogus step *** + +* Now we decide not to specialise the call + $fSourcePix @Int $fIndexInt + because we alredy have a RULE that matches it + +* Finally the simplifer rewrites + dSource = $fSourcePix @Int $fIndexInt + ==> dSource = $s$fSourcePix + +Disaster. Now we have + +Rewrite dSource's RHS to $s$fSourcePix Disaster + dSource = $s$fSourcePix + dIndex = sc_sel dSource + $s$fSourcePix = MkSource dIndex ... + +Solution: filterCalls should have stopped the bogus step, +by seeing that dIndex transitively uses $fSourcePix. But +it can only do that if it sees all the dict_binds. Wow. + +-------------- +Here's another example (#13429). Suppose we have + class Monoid v => C v a where ... + +We start with a call + f @ [Integer] @ Integer $fC[]Integer + +Specialising call to 'f' gives dict bindings + $dMonoid_1 :: Monoid [Integer] + $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer + + $dC_1 :: C [Integer] (Node [Integer] Integer) + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + +...plus a recursive call to + f @ [Integer] @ (Node [Integer] Integer) $dC_1 + +Specialising that call gives + $dMonoid_2 :: Monoid [Integer] + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + + $dC_2 :: C [Integer] (Node [Integer] Integer) + $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 + +Now we have two calls to the imported function + M.$fCvNode :: Monoid v => C v a + M.$fCvNode @v @a m = C m some_fun + +But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) +for specialisation, else we get: + + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + $s$fCvNode = C $dMonoid_2 ... + RULE M.$fCvNode [Integer] _ _ = $s$fCvNode + +Now use the rule to rewrite the call in the RHS of $dC_1 +and we get a loop! + + +Note [specImport call stack] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising an imports function 'f', we may get new calls +of an imported fuction 'g', which we want to specialise in turn, +and similarly specialising 'g' might expose a new call to 'h'. + +We track the stack of enclosing functions. So when specialising 'h' we +haev a specImport call stack of [g,f]. We do this for two reasons: +* Note [Warning about missed specialisations] +* Note [Avoiding recursive specialisation] + +Note [Warning about missed specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose * In module Lib, you carefully mark a function 'foo' INLINABLE * Import Lib(foo) into another module M @@ -807,6 +931,16 @@ is what Opt_WarnAllMissedSpecs does. ToDo: warn about missed opportunities for local functions. +Note [Avoiding recursive specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we specialise 'f' we may find new overloaded calls to 'g', 'h' in +'f's RHS. So we want to specialise g,h. But we don't want to +specialise f any more! It's possible that f's RHS might have a +recursive yet-more-specialised call, so we'd diverge in that case. +And if the call is to the same type, one specialisation is enough. +Avoiding this recursive specialisation loop is one reason for the +'callers' stack passed to specImports and specImport. + Note [Specialise imported INLINABLE things] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ What imported functions do we specialise? The basic set is @@ -842,15 +976,6 @@ make sure that f_spec is recursive. Easiest thing is to make all the specialisations for imported bindings recursive. -Note [Avoiding recursive specialisation] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When we specialise 'f' we may find new overloaded calls to 'g', 'h' in -'f's RHS. So we want to specialise g,h. But we don't want to -specialise f any more! It's possible that f's RHS might have a -recursive yet-more-specialised call, so we'd diverge in that case. -And if the call is to the same type, one specialisation is enough. -Avoiding this recursive specialisation loop is the reason for the -'done' VarSet passed to specImports and specImport. ************************************************************************ * * @@ -992,7 +1117,8 @@ specCase env scrut' case_bndr [(con, args, rhs)] ; (rhs', rhs_uds) <- specExpr env_rhs' rhs ; let scrut_bind = mkDB (NonRec case_bndr_flt scrut') case_bndr_set = unitVarSet case_bndr_flt - sc_binds = [(NonRec sc_arg_flt sc_rhs, case_bndr_set) + sc_binds = [ DB { db_bind = NonRec sc_arg_flt sc_rhs + , db_fvs = case_bndr_set } | (sc_arg_flt, sc_rhs) <- sc_args_flt `zip` sc_rhss ] flt_binds = scrut_bind : sc_binds (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds @@ -1115,7 +1241,7 @@ specBind rhs_env (NonRec fn rhs) body_uds else -- No call in final_uds mentions bound variables, -- so we can just leave the binding here - return (map fst final_binds, free_uds) } + return (map db_bind final_binds, free_uds) } specBind rhs_env (Rec pairs) body_uds @@ -1142,7 +1268,7 @@ specBind rhs_env (Rec pairs) body_uds ; if float_all then return ([], final_uds `snocDictBind` final_bind) else - return ([fst final_bind], final_uds) } + return ([db_bind final_bind], final_uds) } --------------------------- @@ -1621,8 +1747,10 @@ In general, we need only make this Rec if Note [Avoiding loops] ~~~~~~~~~~~~~~~~~~~~~ When specialising /dictionary functions/ we must be very careful to -avoid building loops. Here is an example that bit us badly: #3591 +avoid building loops. Here is an example that bit us badly, on +several distinct occasions. +Here is one: #3591 class Eq a => C a instance Eq [a] => C [a] @@ -1637,13 +1765,11 @@ This translates to None of these definitions is recursive. What happened was that we generated a specialisation: - RULE forall d. dfun T d = dT :: C [T] dT = (MkD a d (meth d)) [T/a, d1/d] = MkD T d1 (meth d1) But now we use the RULE on the RHS of d2, to get - d2 = dT = MkD d1 (meth d1) d1 = $p1 d2 @@ -1660,46 +1786,6 @@ Solution: (directly or indirectly) on the dfun we are specialising. This is done by 'filterCalls' --------------- -Here's another example, this time for an imported dfun, so the call -to filterCalls is in specImports (#13429). Suppose we have - class Monoid v => C v a where ... - -We start with a call - f @ [Integer] @ Integer $fC[]Integer - -Specialising call to 'f' gives dict bindings - $dMonoid_1 :: Monoid [Integer] - $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer - - $dC_1 :: C [Integer] (Node [Integer] Integer) - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - -...plus a recursive call to - f @ [Integer] @ (Node [Integer] Integer) $dC_1 - -Specialising that call gives - $dMonoid_2 :: Monoid [Integer] - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - - $dC_2 :: C [Integer] (Node [Integer] Integer) - $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 - -Now we have two calls to the imported function - M.$fCvNode :: Monoid v => C v a - M.$fCvNode @v @a m = C m some_fun - -But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) -for specialisation, else we get: - - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - $s$fCvNode = C $dMonoid_2 ... - RULE M.$fCvNode [Integer] _ _ = $s$fCvNode - -Now use the rule to rewrite the call in the RHS of $dC_1 -and we get a loop! - -------------- Here's yet another example @@ -2227,7 +2313,7 @@ data UsageDetails -- | A 'DictBind' is a binding along with a cached set containing its free -- variables (both type variables and dictionaries) -type DictBind = (CoreBind, VarSet) +data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet } {- Note [Floated dictionary bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2256,6 +2342,11 @@ So the DictBinds in (ud_binds :: Bag DictBind) may contain non-dictionary bindings too. -} +instance Outputable DictBind where + ppr (DB { db_bind = bind, db_fvs = fvs }) + = text "DB" <+> braces (sep [ text "bind:" <+> ppr bind + , text "fvs: " <+> ppr fvs ]) + instance Outputable UsageDetails where ppr (MkUD { ud_binds = dbs, ud_calls = calls }) = text "MkUD" <+> braces (sep (punctuate comma @@ -2304,8 +2395,8 @@ ppr_call_key_ty (SpecDict _) = Nothing ppr_call_key_ty UnspecArg = Nothing instance Outputable CallInfo where - ppr (CI { ci_key = key, ci_fvs = fvs }) - = text "CI" <> braces (hsep [ fsep (mapMaybe ppr_call_key_ty key), ppr fvs ]) + ppr (CI { ci_key = key, ci_fvs = _fvs }) + = text "CI" <> braces (sep (map ppr key)) unionCalls :: CallDetails -> CallDetails -> CallDetails unionCalls c1 c2 = plusDVarEnv_C unionCallInfoSet c1 c2 @@ -2491,11 +2582,11 @@ plusUDs (MkUD {ud_binds = db1, ud_calls = calls1}) ----------------------------- _dictBindBndrs :: Bag DictBind -> [Id] -_dictBindBndrs dbs = foldr ((++) . bindersOf . fst) [] dbs +_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs -- | Construct a 'DictBind' from a 'CoreBind' mkDB :: CoreBind -> DictBind -mkDB bind = (bind, bind_fvs bind) +mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind } -- | Identify the free variables of a 'CoreBind' bind_fvs :: CoreBind -> VarSet @@ -2526,17 +2617,18 @@ pair_fvs (bndr, rhs) = exprSomeFreeVars interesting rhs -- | Flatten a set of "dumped" 'DictBind's, and some other binding -- pairs, into a single recursive binding. -recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind ->DictBind +recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind -> DictBind recWithDumpedDicts pairs dbs - = (Rec bindings, fvs) + = DB { db_bind = Rec bindings, db_fvs = fvs } where - (bindings, fvs) = foldr add - ([], emptyVarSet) - (dbs `snocBag` mkDB (Rec pairs)) - add (NonRec b r, fvs') (pairs, fvs) = - ((b,r) : pairs, fvs `unionVarSet` fvs') - add (Rec prs1, fvs') (pairs, fvs) = - (prs1 ++ pairs, fvs `unionVarSet` fvs') + (bindings, fvs) = foldr add ([], emptyVarSet) + (dbs `snocBag` mkDB (Rec pairs)) + add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc) + = case bind of + NonRec b r -> ((b,r) : prs_acc, fvs') + Rec prs1 -> (prs1 ++ prs_acc, fvs') + where + fvs' = fvs_acc `unionVarSet` fvs snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails -- Add ud_binds to the tail end of the bindings in uds @@ -2556,13 +2648,13 @@ wrapDictBinds :: Bag DictBind -> [CoreBind] -> [CoreBind] wrapDictBinds dbs binds = foldr add binds dbs where - add (bind,_) binds = bind : binds + add (DB { db_bind = bind }) binds = bind : binds wrapDictBindsE :: Bag DictBind -> CoreExpr -> CoreExpr wrapDictBindsE dbs expr = foldr add expr dbs where - add (bind,_) expr = Let bind expr + add (DB { db_bind = bind }) expr = Let bind expr ---------------------- dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, Bag DictBind) @@ -2624,9 +2716,10 @@ filterCalls (CIS fn call_bag) dbs -- (_,_,dump_set) = splitDictBinds dbs {fn} -- But this variant is shorter - go so_far (db,fvs) | fvs `intersectsVarSet` so_far - = extendVarSetList so_far (bindersOf db) - | otherwise = so_far + go so_far (DB { db_bind = bind, db_fvs = fvs }) + | fvs `intersectsVarSet` so_far + = extendVarSetList so_far (bindersOf bind) + | otherwise = so_far ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) @@ -2643,8 +2736,9 @@ splitDictBinds dbs bndr_set -- Important that it's foldl' not foldr; -- we're accumulating the set of dumped ids in dump_set where - split_db (free_dbs, dump_dbs, dump_idset) db@(bind, fvs) - | dump_idset `intersectsVarSet` fvs -- Dump it + split_db (free_dbs, dump_dbs, dump_idset) db + | DB { db_bind = bind, db_fvs = fvs } <- db + , dump_idset `intersectsVarSet` fvs -- Dump it = (free_dbs, dump_dbs `snocBag` db, extendVarSetList dump_idset (bindersOf bind)) ===================================== testsuite/tests/simplCore/should_run/T17151.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE FlexibleContexts #-} +module Main where + +import T17151a + +main :: IO () +main = do + let ys :: Array P Int Int + ys = computeS (makeArray D 1 (const 5)) + applyStencil :: + (Source P ix Int, Load D ix Int) + => Stencil ix Int Int + -> Array P ix Int + -> Array P ix Int + applyStencil s = computeS . mapStencil s + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) ===================================== testsuite/tests/simplCore/should_run/T17151.stdout ===================================== @@ -0,0 +1,2 @@ +55 +55 ===================================== testsuite/tests/simplCore/should_run/T17151a.hs ===================================== @@ -0,0 +1,205 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE EmptyDataDecls #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +module T17151a + ( computeS + , Stencil + , P(..) + , D(..) + , makeConvolutionStencilFromKernel + , mapStencil + , Array + , Construct(..) + , Source(..) + , Load(..) + , Mutable(..) + ) where + +import Control.Monad.ST +import Data.Functor.Identity +import GHC.STRef +import GHC.ST +import GHC.Exts +import Unsafe.Coerce +import Data.Kind + +---- Hacked up stuff to simulate primitive package +class Prim e where + indexByteArray :: ByteArray -> Int -> e + sizeOf :: e ->Int +instance Prim Int where + indexByteArray _ _ = 55 + sizeOf _ = 99 + +data ByteArray = BA +type MutableByteArray s = STRef s Int + +class Monad m => PrimMonad m where + type PrimState m + primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a +instance PrimMonad (ST s) where + type PrimState (ST s) = s + primitive = ST + +unsafeFreezeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> m ByteArray +unsafeFreezeByteArray a = return (unsafeCoerce a) + +newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m)) +newByteArray (I# n#) + = primitive (\s# -> case newMutVar# 33 s# of + (# s'#, arr# #) -> (# s'#, STRef arr# #)) + +writeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> e -> m () +writeByteArray _ _ _ = return () + +----- End of hacked up stuff + +-------------- +newtype Stencil ix e a = + Stencil ((ix -> e) -> ix -> a) + +mapStencil :: Source r ix e => Stencil ix e a -> Array r ix e -> Array D ix a +mapStencil (Stencil stencilF) arr = DArray (size arr) (stencilF (unsafeIndex arr)) +{-# INLINE mapStencil #-} + +makeConvolutionStencilFromKernel + :: (Source r ix e, Num e) + => Array r ix e + -> Stencil ix e e +makeConvolutionStencilFromKernel arr = Stencil stencil + where + sz = size arr + sCenter = liftIndex (`quot` 2) sz + stencil getVal ix = + runIdentity $ + loopM 0 (< totalElem sz) (+ 1) 0 $ \i a -> + pure $ accum a (fromLinearIndex sz i) (unsafeLinearIndex arr i) + where + ixOff = liftIndex2 (+) ix sCenter + accum acc kIx kVal = getVal (liftIndex2 (-) ixOff kIx) * kVal + acc + {-# INLINE accum #-} + {-# INLINE stencil #-} +{-# INLINE makeConvolutionStencilFromKernel #-} + + +computeS :: (Mutable r ix e, Load r' ix e) => Array r' ix e -> Array r ix e +computeS arr = runST $ do + marr <- unsafeNew (size arr) + unsafeLoadIntoS marr arr + unsafeFreeze marr +{-# INLINE computeS #-} + + +data D = D deriving Show + +data instance Array D ix e = DArray{dSize :: ix, + dIndex :: ix -> e} + +instance Index ix => Construct D ix e where + makeArray _ = DArray + {-# INLINE makeArray #-} + +instance Index ix => Source D ix e where + unsafeIndex = dIndex + {-# INLINE unsafeIndex #-} + +instance Index ix => Load D ix e where + size = dSize + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +data P = P deriving Show + +data instance Array P ix e = PArray ix ByteArray + +instance (Prim e, Index ix) => Construct P ix e where + makeArray _ sz f = computeS (makeArray D sz f) + {-# INLINE makeArray #-} + +instance (Prim e, Index ix) => Source P ix e where + unsafeIndex (PArray sz a) = indexByteArray a . toLinearIndex sz + {-# INLINE unsafeIndex #-} + +instance (Prim e, Index ix) => Mutable P ix e where + data MArray s P ix e = MPArray ix (MutableByteArray s) + unsafeFreeze (MPArray sz a) = PArray sz <$> unsafeFreezeByteArray a + {-# INLINE unsafeFreeze #-} + unsafeNew sz = MPArray sz <$> newByteArray (totalElem sz * eSize) + where + eSize = sizeOf (undefined :: e) + {-# INLINE unsafeNew #-} + unsafeLinearWrite (MPArray _ ma) = writeByteArray ma + {-# INLINE unsafeLinearWrite #-} + + +instance (Prim e, Index ix) => Load P ix e where + size (PArray sz _) = sz + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +unsafeLinearIndex :: Source r ix e => Array r ix e -> Int -> e +unsafeLinearIndex arr = unsafeIndex arr . fromLinearIndex (size arr) +{-# INLINE unsafeLinearIndex #-} + + +loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a +loopM init' condition increment initAcc f = go init' initAcc + where + go step acc + | condition step = f step acc >>= go (increment step) + | otherwise = return acc +{-# INLINE loopM #-} + +splitLinearlyWith_ :: + Monad m => Int -> (Int -> b) -> (Int -> b -> m ()) -> m () +splitLinearlyWith_ totalLength index write = + loopM 0 (< totalLength) (+1) () $ \i () -> write i (index i) +{-# INLINE splitLinearlyWith_ #-} + + +data family Array r ix e :: Type + +class Index ix => Construct r ix e where + makeArray :: r -> ix -> (ix -> e) -> Array r ix e + +class Load r ix e => Source r ix e where + unsafeIndex :: Array r ix e -> ix -> e + +class Index ix => Load r ix e where + size :: Array r ix e -> ix + loadArrayM :: Monad m => Array r ix e -> (Int -> e -> m ()) -> m () + unsafeLoadIntoS :: + (Mutable r' ix e, PrimMonad m) => MArray (PrimState m) r' ix e -> Array r ix e -> m () + unsafeLoadIntoS marr arr = loadArrayM arr (unsafeLinearWrite marr) + {-# INLINE unsafeLoadIntoS #-} + +class (Construct r ix e, Source r ix e) => Mutable r ix e where + data MArray s r ix e :: Type + unsafeFreeze :: PrimMonad m => MArray (PrimState m) r ix e -> m (Array r ix e) + unsafeNew :: PrimMonad m => ix -> m (MArray (PrimState m) r ix e) + unsafeLinearWrite :: PrimMonad m => MArray (PrimState m) r ix e -> Int -> e -> m () + + +class (Eq ix, Ord ix, Show ix) => + Index ix + where + totalElem :: ix -> Int + liftIndex2 :: (Int -> Int -> Int) -> ix -> ix -> ix + liftIndex :: (Int -> Int) -> ix -> ix + toLinearIndex :: ix -> ix -> Int + fromLinearIndex :: ix -> Int -> ix + +instance Index Int where + totalElem = id + toLinearIndex _ = id + fromLinearIndex _ = id + liftIndex f = f + liftIndex2 f = f ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -92,3 +92,4 @@ test('T15840', normal, compile_and_run, ['']) test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) +test('T17151', [], multimod_compile_and_run, ['T17151', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8927189a1abc3f107bc2c1e06df3dbe7d5e2bd98...fd12d84eaa2e16a96ccbe4bdcfc8309f1312d4be -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8927189a1abc3f107bc2c1e06df3dbe7d5e2bd98...fd12d84eaa2e16a96ccbe4bdcfc8309f1312d4be You're receiving 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 3 12:54:12 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Fri, 03 Apr 2020 08:54:12 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18005 Message-ID: <5e8731f48ba0d_616776d1c742762838@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18005 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18005 You're receiving 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 3 13:58:46 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 09:58:46 -0400 Subject: [Git][ghc/ghc][wip/T17978] 10 commits: Re-engineer the binder-swap transformation Message-ID: <5e8741163c8c0_61673f81bb9e8b04278596@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T17978 at Glasgow Haskell Compiler / GHC Commits: b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - b2dfb01d by Simon Jakobi at 2020-04-02T19:21:50+02:00 Combine STG free variable traversals Closes #17978. - - - - - 04c40d8e by Simon Jakobi at 2020-04-03T15:55:17+02:00 Remove the STG binds forcing step With a single pass over the bindings, this shouldn't be necessary any more. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/DepAnal.hs - compiler/GHC/Stg/Pipeline.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/main/SysTools/Terminal.hs - compiler/prelude/primops.txt.pp - compiler/typecheck/TcSplice.hs - hadrian/hadrian.cabal - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Rules/Library.hs - hadrian/stack.yaml - includes/stg/MiscClosures.h - rts/StgMiscClosures.cmm - rts/sm/GC.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/639083550f120583d0ce6cf9abf7c0d772ab0639...04c40d8ebd44bfe6c2a0269bc1328037fe4f209e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/639083550f120583d0ce6cf9abf7c0d772ab0639...04c40d8ebd44bfe6c2a0269bc1328037fe4f209e You're receiving 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 3 14:32:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 03 Apr 2020 10:32:13 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e8748edafe8d_6167134ebbc42798630@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: ca019339 by Ben Gamari at 2020-04-03T10:32:03-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Metric Decrease: T12234 T13035 T13719 T14683 T4801 T5631 T9020 T9961 Metric Increase: T12150 T12425 T14697 T15426 T1969 T5837 T9203 T9872a T9872b T9872c T9872d - - - - - 9 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1001,10 +1001,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1023,6 +1019,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1306,8 +1318,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1552,14 +1563,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1568,8 +1574,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3021,8 +3019,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,73 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ca019339174f3c80e1099258dd1dcca8c96c8809 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ca019339174f3c80e1099258dd1dcca8c96c8809 You're receiving 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 3 14:32:30 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 10:32:30 -0400 Subject: [Git][ghc/ghc][wip/T17978] Remove annTopBindingsFreeVars Message-ID: <5e8748fe744d9_61673f8199536d9427994bd@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T17978 at Glasgow Haskell Compiler / GHC Commits: d33b3085 by Simon Jakobi at 2020-04-03T16:32:09+02:00 Remove annTopBindingsFreeVars - - - - - 1 changed file: - compiler/GHC/Stg/FVs.hs Changes: ===================================== compiler/GHC/Stg/FVs.hs ===================================== @@ -38,7 +38,6 @@ Top-level closure bindings never capture variables as all of their free variables are global. -} module GHC.Stg.FVs ( - annTopBindingsFreeVars, annBindingFreeVars ) where @@ -65,14 +64,6 @@ addLocals :: [Id] -> Env -> Env addLocals bndrs env = env { locals = extendVarSetList (locals env) bndrs } --- | Annotates a top-level STG binding group with its free variables. -annTopBindingsFreeVars :: [StgTopBinding] -> [CgStgTopBinding] -annTopBindingsFreeVars = map go - where - go (StgTopStringLit id bs) = StgTopStringLit id bs - go (StgTopLifted bind) - = StgTopLifted (annBindingFreeVars bind) - -- | Annotates an STG binding with its free variables. annBindingFreeVars :: StgBinding -> CgStgBinding annBindingFreeVars = fst . binding emptyEnv emptyDVarSet View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d33b3085fe9920862849fb8284269350a89dc9cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d33b3085fe9920862849fb8284269350a89dc9cd You're receiving 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 3 14:44:05 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 03 Apr 2020 10:44:05 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] DmdAnal: Reflect precise exceptions in demand types Message-ID: <5e874bb584d27_6167134ebbc427997c0@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 7a034c54 by Sebastian Graf at 2020-04-03T16:43:33+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7a034c54d6b261ae15438276f5d9843c4dac6ac8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7a034c54d6b261ae15438276f5d9843c4dac6ac8 You're receiving 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 3 14:44:22 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Fri, 03 Apr 2020 10:44:22 -0400 Subject: [Git][ghc/ghc][wip/T18005] Enable ImpredicativeTypes internally when typechecking selector bindings Message-ID: <5e874bc64a034_61673f81bb9e8b042800220@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18005 at Glasgow Haskell Compiler / GHC Commits: 2e0f90b7 by Ryan Scott at 2020-04-03T10:44:05-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 3 changed files: - compiler/typecheck/TcTyDecls.hs - + testsuite/tests/typecheck/should_compile/T18005.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/typecheck/TcTyDecls.hs ===================================== @@ -67,6 +67,7 @@ import Bag import FastString import FV import GHC.Types.Module +import qualified GHC.LanguageExtensions as LangExt import Control.Monad @@ -831,6 +832,8 @@ tcRecSelBinds :: [(Id, LHsBind GhcRn)] -> TcM TcGblEnv tcRecSelBinds sel_bind_prs = tcExtendGlobalValEnv [sel_id | (L _ (IdSig _ sel_id)) <- sigs] $ do { (rec_sel_binds, tcg_env) <- discardWarnings $ + -- See Note [Impredicative record selectors] + setXOptM LangExt.ImpredicativeTypes $ tcValBinds TopLevel binds sigs getGblEnv ; return (tcg_env `addTypecheckedBinds` map snd rec_sel_binds) } where @@ -1029,4 +1032,29 @@ The selector we want for fld looks like this: The scrutinee of the case has type :R7T (Maybe b), which can be gotten by applying the eq_spec to the univ_tvs of the data con. +Note [Impredicative record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There are situations where generating code for record selectors requires the +use of ImpredicativeTypes. Here is one example (adapted from #18005): + + type S = (forall b. b -> b) -> Int + data T = MkT {unT :: S} + | Dummy + +We want to generate HsBinds for unT that look something like this: + + unT :: S + unT (MkT x) = x + unT _ = recSelError "unT"# + +Note that the type of recSelError is `forall r (a :: TYPE r). Addr# -> a`. +Therefore, when used in the right-hand side of `unT`, GHC attempts to +instantiate `a` with `(forall b. b -> b) -> Int`, which is impredicative. +To make sure that GHC is OK with this, we enable ImpredicativeTypes interally +when typechecking these HsBinds so that the user does not have to. + +Although ImpredicativeTypes is somewhat fragile and unpredictable in GHC right +now, it will become robust when Quick Look impredicativity is implemented. In +the meantime, using ImpredicativeTypes to instantiate the `a` type variable in +recSelError's type does actually work, so its use here is benign. -} ===================================== testsuite/tests/typecheck/should_compile/T18005.hs ===================================== @@ -0,0 +1,30 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ViewPatterns #-} +module T18005 where + +type S1 = Int -> (forall a. a -> a) -> Int + +data T1a = MkT1a {unT1a :: S1} + | Dummy1 + +newtype T1b = MkT1b S1 + +unT1b' :: T1b -> S1 +unT1b' (MkT1b x) = x + +pattern MkT1b' :: S1 -> T1b +pattern MkT1b' {unT1b} <- (unT1b' -> unT1b) + +type S2 = Int -> forall a. a -> a + +data T2a = MkT2a {unT2a :: S2} + | Dummy2 + +newtype T2b = MkT2b S2 + +unT2b' :: T2b -> S2 +unT2b' (MkT2b x) = x + +pattern MkT2b' :: S2 -> T2b +pattern MkT2b' {unT2b} <- (unT2b' -> unT2b) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -701,3 +701,4 @@ test('T17710', normal, compile, ['']) test('T17792', normal, compile, ['']) test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) +test('T18005', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2e0f90b7084052aa9473a326b14b9247b3fde4cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2e0f90b7084052aa9473a326b14b9247b3fde4cc You're receiving 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 3 15:22:20 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 11:22:20 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/revert_pragma_commit Message-ID: <5e8754ac3cd56_61673f81bb9e8b0428144e4@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/revert_pragma_commit at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/revert_pragma_commit You're receiving 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 3 15:33:14 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 11:33:14 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/andreask/revert_pragma_commit Message-ID: <5e87573a94d33_61673f81ef22dee4282583e@gitlab.haskell.org.mail> Andreas Klebinger deleted branch wip/andreask/revert_pragma_commit 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 3 17:06:19 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 13:06:19 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Rework treatment of `elem`. Add UTF8 GHC.CString functions. Message-ID: <5e876d0b4ff67_6167136dfb9c283536a@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 76eeafee by Andreas Klebinger at 2020-04-03T19:01:00+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. This now also works for unboxed string literals via a builtin rule. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors and was required to support this transformation for utf8 encoded unboxed strings. - - - - - 13 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/prelude/PrelNames.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.Make ( sortQuantVars, castBottomExpr, -- * Constructing boxed literals + trueExpr, falseExpr, mkWordExpr, mkWordExprWord, mkIntExpr, mkIntExprInt, mkIntegerExpr, mkNaturalExpr, @@ -248,6 +249,10 @@ castBottomExpr e res_ty ************************************************************************ -} +trueExpr, falseExpr :: CoreExpr +trueExpr = Var trueDataConId +falseExpr = Var falseDataConId + -- | Create a 'CoreExpr' which will evaluate to the given @Int@ mkIntExpr :: Platform -> Integer -> CoreExpr -- Result = I# i :: Int mkIntExpr platform i = mkCoreConApps intDataCon [mkIntLit platform i] ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -34,7 +34,8 @@ import GHC.Core import GHC.Core.Make import GHC.Types.Id import GHC.Types.Literal -import GHC.Core.SimpleOpt ( exprIsLiteral_maybe ) +import GHC.Core.SimpleOpt ( exprIsLiteral_maybe, exprIsLambda_maybe + , exprIsStrippableLiteral_maybe ) import PrimOp ( PrimOp(..), tagToEnumKey ) import TysWiredIn import TysPrim @@ -57,6 +58,7 @@ import GHC.Types.Basic import GHC.Platform import Util import GHC.Core.Coercion (mkUnbranchedAxInstCo,mkSymCo,Role(..)) +import Encoding (utf8DecodeByteString) import Control.Applicative ( Alternative(..) ) @@ -67,6 +69,7 @@ import Data.Int import Data.Ratio import Data.Word + {- Note [Constant folding] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1254,11 +1257,18 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, + BuiltinRule { ru_name = fsLit "AppendLitStringUtf8", + ru_fn = unpackCStringFoldrUtf8Name, + ru_nargs = 4, ru_try = match_append_lit_utf8 }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, ru_nargs = 2, ru_try = \_ _ _ -> match_inline }, + + -- See Note [Compiling `elem` on Strings] in CString.hs + BuiltinRule { ru_name = fsLit "ElemLitString", ru_fn = elemName, + ru_nargs = 4, ru_try = match_elem }, BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId, ru_nargs = 4, ru_try = \_ _ _ -> match_magicDict }, @@ -1430,11 +1440,20 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo" c (unpackFoldrCString*# "baz" c n) +-- = unpackFoldrCString*# "foobaz" c n + +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey + +-- CStringUTF8 version +match_append_lit_utf8 :: RuleFun +match_append_lit_utf8 = match_append_lit unpackCStringFoldrUtf8IdKey -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,7 +1466,7 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey + , unpk `hasKey` foldVariant , cheapEqExpr' tickishFloatable c1 c2 , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 , c2Ticks <- stripTicksTopT tickishFloatable c2 @@ -1460,23 +1479,79 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)) = s1==s2 +-- Also matches unpackCStringUtf8# match_eq_string :: RuleFun match_eq_string _ id_unf _ [Var unpk1 `App` lit1, Var unpk2 `App` lit2] - | unpk1 `hasKey` unpackCStringIdKey - , unpk2 `hasKey` unpackCStringIdKey + | unpk_key1 <- getUnique unpk1 + , unpk_key2 <- getUnique unpk2 + , unpk_key1 == unpk_key2 + , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 = Just (if s1 == s2 then trueValBool else falseValBool) match_eq_string _ _ _ _ = Nothing +--------------------------------------------------- +-- The rule is this: +-- elem x +-- = case x of C# x' +-- case x' of - +-- 'a'# -> True +-- 'b'# -> True +-- 'c'# -> True +-- _ -> False +-- +-- Where knownString is one of: +-- * (build ((unpackFoldrCString# "abc"#) +-- * (unpackCString*# "abc"#) +-- Limits matches to strings <=500 bytes. +-- Also matches utf8 versions. +-- See Note [Compiling `elem` on Strings] in CString.hs + +match_elem :: RuleFun +match_elem _ id_unf _ [Type ty, _dict, x, xs] + -- elem on string + | ty `eqType` charTy + , ( xsTicks, xsApp) <- stripTicksTop tickishFloatable xs + -- Can we get the string + , Just (lam_ticks, litExpr) <- getLitStringExpr xsApp + , Just (LitString s1, litTicks) <- exprIsStrippableLiteral_maybe id_unf tickishFloatable litExpr + -- For really large strings we fall back to the default implementation. + , BS.length s1 <= 500 + = let elem_string = nubSort $ utf8DecodeByteString s1 :: String + x_id = mkWildValBinder charTy :: Id + x_prim_id = mkWildValBinder charPrimTy :: Id + switch = Case (Var x_prim_id) x_prim_id boolTy + ((DEFAULT, [], falseExpr):foldr mkCharAlt [] elem_string) + mkCharAlt :: Char -> [CoreAlt] -> [CoreAlt] + mkCharAlt c alts = (LitAlt (mkLitChar c), [], trueExpr):alts + in Just $ mkTicks (xsTicks ++ lam_ticks ++ litTicks) + $ Case x x_id boolTy [(DataAlt charDataCon, [x_prim_id], switch)] + where + getLitStringExpr :: CoreExpr -> Maybe ([Tickish Id], CoreExpr) + getLitStringExpr app + -- (build ((unpackFoldrCString*# "abc"#))) + | (Var build `App` _char_ty `App` unf_str_app) <- app + , build `hasKey` buildIdKey + , Just (_arg, (Var unfold_str `App` _ty2 `App` lit1), lam_ticks) + <- exprIsLambda_maybe id_unf unf_str_app + , getUnique unfold_str `elem` [unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey] + = Just (lam_ticks, lit1) + -- (unpackCString*# "abc"#) + | (Var unpackVar `App` lit1) <- app + , getUnique unpackVar `elem` [unpackCStringIdKey, unpackCStringUtf8IdKey] + = Just ([], lit1) + | otherwise = Nothing + +match_elem _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.SimpleOpt ( -- ** Predicates on expressions exprIsConApp_maybe, exprIsLiteral_maybe, exprIsLambda_maybe, + exprIsStrippableLiteral_maybe, -- ** Coercions and casts pushCoArg, pushCoValArg, pushCoTyArg, collectBindersPushingCo @@ -1156,6 +1157,20 @@ exprIsLiteral_maybe env@(_, id_unf) e -> exprIsLiteral_maybe env rhs _ -> Nothing +exprIsStrippableLiteral_maybe :: InScopeEnv -> (Tickish Id -> Bool) -> CoreExpr -> Maybe (Literal, [Tickish Id]) +-- Similar to exprIsLiteral_maybe but fails instead of dropping ticks +-- This means Tick t (Lit l) *can return Nothing*. So use with care +exprIsStrippableLiteral_maybe (_, id_unf) strip expr + = go [] expr + where + go ts e = case e of + Lit l -> Just (l,ts) + Tick t e' + | strip t -> go (t:ts) e' + Var v | Just rhs <- expandUnfolding_maybe (id_unf v) + -> go ts rhs + _ -> Nothing + {- Note [exprIsLambda_maybe] ~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -340,8 +340,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, -- Overloaded lists isListClassName, @@ -352,6 +352,7 @@ basicKnownKeyNames -- List operations concatName, filterName, mapName, zipName, foldrName, buildName, augmentName, appendName, + elemName, -- FFI primitive types that are not wired-in. stablePtrTyConName, ptrTyConName, funPtrTyConName, @@ -677,9 +678,10 @@ ordClass_RDR = nameRdrName ordClassName enumClass_RDR = nameRdrName enumClassName monadClass_RDR = nameRdrName monadClassName -map_RDR, append_RDR :: RdrName +map_RDR, append_RDR, elem_RDR :: RdrName map_RDR = nameRdrName mapName append_RDR = nameRdrName appendName +elem_RDR = nameRdrName elemName foldr_RDR, build_RDR, returnM_RDR, bindM_RDR, failM_RDR :: RdrName @@ -712,11 +714,12 @@ ioDataCon_RDR :: RdrName ioDataCon_RDR = nameRdrName ioDataConName eqString_RDR, unpackCString_RDR, unpackCStringFoldr_RDR, - unpackCStringUtf8_RDR :: RdrName + unpackCStringFoldrUtf8_RDR, unpackCStringUtf8_RDR :: RdrName eqString_RDR = nameRdrName eqStringName unpackCString_RDR = nameRdrName unpackCStringName unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name +unpackCStringFoldrUtf8_RDR = nameRdrName unpackCStringFoldrUtf8Name newStablePtr_RDR :: RdrName newStablePtr_RDR = nameRdrName newStablePtrName @@ -1006,11 +1009,12 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name,eqStringName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -1083,7 +1087,7 @@ groupWithName = varQual gHC_EXTS (fsLit "groupWith") groupWithIdKey -- Random PrelBase functions fromStringName, otherwiseIdName, foldrName, buildName, augmentName, - mapName, appendName, assertName, + mapName, appendName, elemName, assertName, breakpointName, breakpointCondName, opaqueTyConName, dollarName :: Name dollarName = varQual gHC_BASE (fsLit "$") dollarIdKey @@ -1097,6 +1101,7 @@ assertName = varQual gHC_BASE (fsLit "assert") assertIdKey breakpointName = varQual gHC_BASE (fsLit "breakpoint") breakpointIdKey breakpointCondName= varQual gHC_BASE (fsLit "breakpointCond") breakpointCondIdKey opaqueTyConName = tcQual gHC_BASE (fsLit "Opaque") opaqueTyConKey +elemName = varQual gHC_LIST (fsLit "elem") elemIdKey fromStringName = varQual dATA_STRING (fsLit "fromString") fromStringClassOpKey -- PrelTup @@ -2081,13 +2086,15 @@ unsafeReflDataConKey = mkPreludeDataConUnique 114 -} wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, + elemIdKey, buildIdKey, errorIdKey, foldrIdKey, recSelErrorIdKey, seqIdKey, eqStringIdKey, noMethodBindingErrorIdKey, nonExhaustiveGuardsErrorIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey :: Unique @@ -2095,27 +2102,29 @@ wildCardKey = mkPreludeMiscIdUnique 0 -- See Note [WildCard absentErrorIdKey = mkPreludeMiscIdUnique 1 augmentIdKey = mkPreludeMiscIdUnique 2 appendIdKey = mkPreludeMiscIdUnique 3 -buildIdKey = mkPreludeMiscIdUnique 4 -errorIdKey = mkPreludeMiscIdUnique 5 -foldrIdKey = mkPreludeMiscIdUnique 6 -recSelErrorIdKey = mkPreludeMiscIdUnique 7 -seqIdKey = mkPreludeMiscIdUnique 8 -absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 9 -eqStringIdKey = mkPreludeMiscIdUnique 10 -noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 11 -nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 12 -runtimeErrorIdKey = mkPreludeMiscIdUnique 13 -patErrorIdKey = mkPreludeMiscIdUnique 14 -realWorldPrimIdKey = mkPreludeMiscIdUnique 15 -recConErrorIdKey = mkPreludeMiscIdUnique 16 -unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 17 -unpackCStringAppendIdKey = mkPreludeMiscIdUnique 18 -unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 19 -unpackCStringIdKey = mkPreludeMiscIdUnique 20 -voidPrimIdKey = mkPreludeMiscIdUnique 21 -typeErrorIdKey = mkPreludeMiscIdUnique 22 -divIntIdKey = mkPreludeMiscIdUnique 23 -modIntIdKey = mkPreludeMiscIdUnique 24 +elemIdKey = mkPreludeMiscIdUnique 4 +buildIdKey = mkPreludeMiscIdUnique 5 +errorIdKey = mkPreludeMiscIdUnique 6 +foldrIdKey = mkPreludeMiscIdUnique 7 +recSelErrorIdKey = mkPreludeMiscIdUnique 8 +seqIdKey = mkPreludeMiscIdUnique 9 +absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 10 +eqStringIdKey = mkPreludeMiscIdUnique 11 +noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 12 +nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 13 +runtimeErrorIdKey = mkPreludeMiscIdUnique 14 +patErrorIdKey = mkPreludeMiscIdUnique 15 +realWorldPrimIdKey = mkPreludeMiscIdUnique 16 +recConErrorIdKey = mkPreludeMiscIdUnique 17 +unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 18 +unpackCStringAppendIdKey = mkPreludeMiscIdUnique 19 +unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 20 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 21 +unpackCStringIdKey = mkPreludeMiscIdUnique 22 +voidPrimIdKey = mkPreludeMiscIdUnique 23 +typeErrorIdKey = mkPreludeMiscIdUnique 24 +divIntIdKey = mkPreludeMiscIdUnique 25 +modIntIdKey = mkPreludeMiscIdUnique 26 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1618,7 +1618,11 @@ iShiftRL# :: Int# -> Int# -> Int# a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# | otherwise = a `uncheckedIShiftRL#` b +------------------------------------------------------------------------ -- Rules for C strings (the functions themselves are now in GHC.CString) +------------------------------------------------------------------------ + +-- Ascii variants {-# RULES "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a @@ -1628,3 +1632,14 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n #-} + +-- Utf8 variants +{-# RULES +"unpackUtf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-listUtf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-appendUtf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + +-- There's a built-in rule (in PrelRules.hs) for +-- unpackFoldrUtf8 "föö" c (unpackFoldrUtf8 "bäz" c n) = unpackFoldrUtf8 "fööbäz" c n + + #-} ===================================== libraries/base/GHC/List.hs ===================================== @@ -1147,11 +1147,12 @@ elem x = any (== x) #else elem _ [] = False elem x (y:ys) = x==y || elem x ys -{-# NOINLINE [1] elem #-} +{-# NOINLINE elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build"[2] forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} + #endif -- | 'notElem' is the negation of 'elem'. @@ -1172,9 +1173,9 @@ notElem x = all (/= x) #else notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys -{-# NOINLINE [1] notElem #-} +{-# NOINLINE notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -9,6 +9,13 @@ * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: Strict IO variants of `hGetContents`, `getContents`, and `readFile`. + * Add rules `unpackUtf8`, `unpack-listUtf8` and `unpack-appendUtf8` to `GHC.Base`. + They correspond to their ascii versions and hopefully make it easier + to handle utf8 encoded strings efficiently. + + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement as expected. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,17 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques + # We only grep for specific patterns to minimize failures when eg core syntax changes + # We expect two unfolds using eqChar + echo $$(cat T17752.dump-simpl | grep unpackFoldrCString) + echo $$(cat T17752.dump-simpl | grep eqChar) + # And two pattern matches + echo $$(cat T17752.dump-simpl | grep "case x1" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,82 @@ +module T17752 where + +-- Should compile to unfoldCStr if the rules fire +isElemLit x = x `elem` "theQuickShinyGHCJumpsOverTheRuleRecursion" +isNotElemLit x = x `notElem` "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion" + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +{- + +Should the grep tests fail make sure the core still behaves +like the one below (or better!) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isElemLit1 = "theQuickShinyGHCJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 20, types: 9, coercions: 0, joins: 0/0} +isElemLit + = \ x -> + unpackFoldrCString# + isElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isNotElemLit1 + = "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 25, types: 10, coercions: 0, joins: 0/0} +isNotElemLit + = \ x -> + case unpackFoldrCString# + isNotElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + of { + False -> True; + True -> False + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'a'# -> True; + 'b'# -> True; + 'c'# -> True + } + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isNotElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'x'# -> True; + 'y'# -> True; + 'z'# -> True + } + } +-} ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,25 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) +GHC.CString.unpackFoldrCString# + case GHC.CString.unpackFoldrCString# +case GHC.Prim.eqChar# x1 y1 of { + case GHC.Prim.eqChar# x1 y1 of { +case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) \ No newline at end of file ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,8 +17,14 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types @@ -71,8 +77,22 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [NOINLINE for unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n +At one stage I had NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. BUT there may be a lot of +literal strings, and making a separate 'unpack' loop for +each is highly gratuitous. See nofib/real/anna/PrettyPrint. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +109,32 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. +If we use the offset start off with the increment and an addition +to get the real address. Which might not be optimized aways. + + Note [Compiling `elem` on Strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The pattern f c = c `elem` "" is quite common in +parsers and often performance critical. + +The fastest way to process this pattern is to transform it +into a case. That is we transform: + + x `elem` "xy" +=> + case x of + 'x' -> True + 'y' -> True + _ -> False + +For this reason there is a BUILTIN rule "ElemLitString" which +performs this rewrite early in the pipeline in case the string +is known and not excessively long. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +157,27 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- See Note [NOINLINE for unpackFoldrCString] +-- {-# INLINE[0] unpackFoldrCString2# #-} +-- unpackFoldrCString2# :: Addr# -> (Char -> a -> a) -> a -> a +-- unpackFoldrCString2# addr f z +-- | isTrue# (ch `eqChar#` '\0'#) = z +-- | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- where +-- -- See Note [unpackCString# iterating over addr] +-- !ch = indexCharOffAddr# addr 0# -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +{-# INLINE[0] unpackFoldrCString# #-} +-- {-# NOINLINE unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z = go str z where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,26 +185,45 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [NOINLINE for unpackFoldrCString] +-- {-# INLINE[0] unpackFoldrCString# #-} +{-# INLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr f z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` unpackFoldrCStringUtf8# addr' f z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. unpackNBytes# :: Addr# -> Int# -> [Char] @@ -174,3 +238,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explizit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,13 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/76eeafeecafd30ef418c38888bdc30eae6444bf0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/76eeafeecafd30ef418c38888bdc30eae6444bf0 You're receiving 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 3 17:19:16 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Fri, 03 Apr 2020 13:19:16 -0400 Subject: [Git][ghc/ghc][wip/tycl-group] 13 commits: Expect T4267 to pass Message-ID: <5e877014d5ee6_61673f81ef22dee4283617c@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/tycl-group at Glasgow Haskell Compiler / GHC Commits: f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - d4fb13df by Vladislav Zavialov at 2020-04-02T14:04:53+03:00 Handle sigs in separate TyClGroups Fixing #12088 implies that we put declarations and definitions in separate TyClGroups. Consider this example: {-# LANGUAGE StandaloneKindSignatures #-} import Data.Kind (Type) type X :: Type data X If the renamer puts type X :: Type and data X into separate TyClGroups, then the type checker must be prepared to handle it. Before this patch, the type checker always assumed that signatures were put into the same TyClGroup as the definition. After this patch, no such assumption is made. - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToC.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Rename/Source.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Types/Unique/Supply.hs - compiler/main/SysTools/Process.hs - compiler/main/SysTools/Terminal.hs - compiler/typecheck/TcDeriv.hs - compiler/typecheck/TcEnv.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcRnTypes.hs - compiler/typecheck/TcSMonad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4fc76474432aa891de56cdcdeddff1ddfeda0025...d4fb13dfb25151bd1c763d867ee197b891f19852 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4fc76474432aa891de56cdcdeddff1ddfeda0025...d4fb13dfb25151bd1c763d867ee197b891f19852 You're receiving 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 3 19:03:34 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 15:03:34 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/andreask/refactor_cmm_datacon Message-ID: <5e878886a5b2f_616713279f6c284853b@gitlab.haskell.org.mail> Andreas Klebinger deleted branch wip/andreask/refactor_cmm_datacon 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 3 19:21:45 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 15:21:45 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Rework treatment of `elem`. Add UTF8 GHC.CString functions. Message-ID: <5e878cc937356_616776d1c74285031d@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 22b9504c by Andreas Klebinger at 2020-04-03T21:21:25+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. This now also works for unboxed string literals via a builtin rule. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors and was required to support this transformation for utf8 encoded unboxed strings. - - - - - 13 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/prelude/PrelNames.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.Make ( sortQuantVars, castBottomExpr, -- * Constructing boxed literals + trueExpr, falseExpr, mkWordExpr, mkWordExprWord, mkIntExpr, mkIntExprInt, mkIntegerExpr, mkNaturalExpr, @@ -248,6 +249,10 @@ castBottomExpr e res_ty ************************************************************************ -} +trueExpr, falseExpr :: CoreExpr +trueExpr = Var trueDataConId +falseExpr = Var falseDataConId + -- | Create a 'CoreExpr' which will evaluate to the given @Int@ mkIntExpr :: Platform -> Integer -> CoreExpr -- Result = I# i :: Int mkIntExpr platform i = mkCoreConApps intDataCon [mkIntLit platform i] ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -34,7 +34,8 @@ import GHC.Core import GHC.Core.Make import GHC.Types.Id import GHC.Types.Literal -import GHC.Core.SimpleOpt ( exprIsLiteral_maybe ) +import GHC.Core.SimpleOpt ( exprIsLiteral_maybe, exprIsLambda_maybe + , exprIsStrippableLiteral_maybe ) import PrimOp ( PrimOp(..), tagToEnumKey ) import TysWiredIn import TysPrim @@ -57,6 +58,7 @@ import GHC.Types.Basic import GHC.Platform import Util import GHC.Core.Coercion (mkUnbranchedAxInstCo,mkSymCo,Role(..)) +import Encoding (utf8DecodeByteString) import Control.Applicative ( Alternative(..) ) @@ -67,6 +69,7 @@ import Data.Int import Data.Ratio import Data.Word + {- Note [Constant folding] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1254,11 +1257,18 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, + BuiltinRule { ru_name = fsLit "AppendLitStringUtf8", + ru_fn = unpackCStringFoldrUtf8Name, + ru_nargs = 4, ru_try = match_append_lit_utf8 }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, ru_nargs = 2, ru_try = \_ _ _ -> match_inline }, + + -- See Note [Compiling `elem` on Strings] in CString.hs + BuiltinRule { ru_name = fsLit "ElemLitString", ru_fn = elemName, + ru_nargs = 4, ru_try = match_elem }, BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId, ru_nargs = 4, ru_try = \_ _ _ -> match_magicDict }, @@ -1430,11 +1440,20 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo" c (unpackFoldrCString*# "baz" c n) +-- = unpackFoldrCString*# "foobaz" c n + +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey + +-- CStringUTF8 version +match_append_lit_utf8 :: RuleFun +match_append_lit_utf8 = match_append_lit unpackCStringFoldrUtf8IdKey -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,7 +1466,7 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey + , unpk `hasKey` foldVariant , cheapEqExpr' tickishFloatable c1 c2 , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 , c2Ticks <- stripTicksTopT tickishFloatable c2 @@ -1460,23 +1479,79 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)) = s1==s2 +-- Also matches unpackCStringUtf8# match_eq_string :: RuleFun match_eq_string _ id_unf _ [Var unpk1 `App` lit1, Var unpk2 `App` lit2] - | unpk1 `hasKey` unpackCStringIdKey - , unpk2 `hasKey` unpackCStringIdKey + | unpk_key1 <- getUnique unpk1 + , unpk_key2 <- getUnique unpk2 + , unpk_key1 == unpk_key2 + , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 = Just (if s1 == s2 then trueValBool else falseValBool) match_eq_string _ _ _ _ = Nothing +--------------------------------------------------- +-- The rule is this: +-- elem x +-- = case x of C# x' +-- case x' of - +-- 'a'# -> True +-- 'b'# -> True +-- 'c'# -> True +-- _ -> False +-- +-- Where knownString is one of: +-- * (build ((unpackFoldrCString# "abc"#) +-- * (unpackCString*# "abc"#) +-- Limits matches to strings <=500 bytes. +-- Also matches utf8 versions. +-- See Note [Compiling `elem` on Strings] in CString.hs + +match_elem :: RuleFun +match_elem _ id_unf _ [Type ty, _dict, x, xs] + -- elem on string + | ty `eqType` charTy + , ( xsTicks, xsApp) <- stripTicksTop tickishFloatable xs + -- Can we get the string + , Just (lam_ticks, litExpr) <- getLitStringExpr xsApp + , Just (LitString s1, litTicks) <- exprIsStrippableLiteral_maybe id_unf tickishFloatable litExpr + -- For really large strings we fall back to the default implementation. + , BS.length s1 <= 500 + = let elem_string = nubSort $ utf8DecodeByteString s1 :: String + x_id = mkWildValBinder charTy :: Id + x_prim_id = mkWildValBinder charPrimTy :: Id + switch = Case (Var x_prim_id) x_prim_id boolTy + ((DEFAULT, [], falseExpr):foldr mkCharAlt [] elem_string) + mkCharAlt :: Char -> [CoreAlt] -> [CoreAlt] + mkCharAlt c alts = (LitAlt (mkLitChar c), [], trueExpr):alts + in Just $ mkTicks (xsTicks ++ lam_ticks ++ litTicks) + $ Case x x_id boolTy [(DataAlt charDataCon, [x_prim_id], switch)] + where + getLitStringExpr :: CoreExpr -> Maybe ([Tickish Id], CoreExpr) + getLitStringExpr app + -- (build ((unpackFoldrCString*# "abc"#))) + | (Var build `App` _char_ty `App` unf_str_app) <- app + , build `hasKey` buildIdKey + , Just (_arg, (Var unfold_str `App` _ty2 `App` lit1), lam_ticks) + <- exprIsLambda_maybe id_unf unf_str_app + , getUnique unfold_str `elem` [unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey] + = Just (lam_ticks, lit1) + -- (unpackCString*# "abc"#) + | (Var unpackVar `App` lit1) <- app + , getUnique unpackVar `elem` [unpackCStringIdKey, unpackCStringUtf8IdKey] + = Just ([], lit1) + | otherwise = Nothing + +match_elem _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.SimpleOpt ( -- ** Predicates on expressions exprIsConApp_maybe, exprIsLiteral_maybe, exprIsLambda_maybe, + exprIsStrippableLiteral_maybe, -- ** Coercions and casts pushCoArg, pushCoValArg, pushCoTyArg, collectBindersPushingCo @@ -1156,6 +1157,20 @@ exprIsLiteral_maybe env@(_, id_unf) e -> exprIsLiteral_maybe env rhs _ -> Nothing +exprIsStrippableLiteral_maybe :: InScopeEnv -> (Tickish Id -> Bool) -> CoreExpr -> Maybe (Literal, [Tickish Id]) +-- Similar to exprIsLiteral_maybe but fails instead of dropping ticks +-- This means Tick t (Lit l) *can return Nothing*. So use with care +exprIsStrippableLiteral_maybe (_, id_unf) strip expr + = go [] expr + where + go ts e = case e of + Lit l -> Just (l,ts) + Tick t e' + | strip t -> go (t:ts) e' + Var v | Just rhs <- expandUnfolding_maybe (id_unf v) + -> go ts rhs + _ -> Nothing + {- Note [exprIsLambda_maybe] ~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -340,8 +340,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, -- Overloaded lists isListClassName, @@ -352,6 +352,7 @@ basicKnownKeyNames -- List operations concatName, filterName, mapName, zipName, foldrName, buildName, augmentName, appendName, + elemName, -- FFI primitive types that are not wired-in. stablePtrTyConName, ptrTyConName, funPtrTyConName, @@ -677,9 +678,10 @@ ordClass_RDR = nameRdrName ordClassName enumClass_RDR = nameRdrName enumClassName monadClass_RDR = nameRdrName monadClassName -map_RDR, append_RDR :: RdrName +map_RDR, append_RDR, elem_RDR :: RdrName map_RDR = nameRdrName mapName append_RDR = nameRdrName appendName +elem_RDR = nameRdrName elemName foldr_RDR, build_RDR, returnM_RDR, bindM_RDR, failM_RDR :: RdrName @@ -712,11 +714,12 @@ ioDataCon_RDR :: RdrName ioDataCon_RDR = nameRdrName ioDataConName eqString_RDR, unpackCString_RDR, unpackCStringFoldr_RDR, - unpackCStringUtf8_RDR :: RdrName + unpackCStringFoldrUtf8_RDR, unpackCStringUtf8_RDR :: RdrName eqString_RDR = nameRdrName eqStringName unpackCString_RDR = nameRdrName unpackCStringName unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name +unpackCStringFoldrUtf8_RDR = nameRdrName unpackCStringFoldrUtf8Name newStablePtr_RDR :: RdrName newStablePtr_RDR = nameRdrName newStablePtrName @@ -1006,11 +1009,12 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name,eqStringName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -1083,7 +1087,7 @@ groupWithName = varQual gHC_EXTS (fsLit "groupWith") groupWithIdKey -- Random PrelBase functions fromStringName, otherwiseIdName, foldrName, buildName, augmentName, - mapName, appendName, assertName, + mapName, appendName, elemName, assertName, breakpointName, breakpointCondName, opaqueTyConName, dollarName :: Name dollarName = varQual gHC_BASE (fsLit "$") dollarIdKey @@ -1097,6 +1101,7 @@ assertName = varQual gHC_BASE (fsLit "assert") assertIdKey breakpointName = varQual gHC_BASE (fsLit "breakpoint") breakpointIdKey breakpointCondName= varQual gHC_BASE (fsLit "breakpointCond") breakpointCondIdKey opaqueTyConName = tcQual gHC_BASE (fsLit "Opaque") opaqueTyConKey +elemName = varQual gHC_LIST (fsLit "elem") elemIdKey fromStringName = varQual dATA_STRING (fsLit "fromString") fromStringClassOpKey -- PrelTup @@ -2081,13 +2086,15 @@ unsafeReflDataConKey = mkPreludeDataConUnique 114 -} wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, + elemIdKey, buildIdKey, errorIdKey, foldrIdKey, recSelErrorIdKey, seqIdKey, eqStringIdKey, noMethodBindingErrorIdKey, nonExhaustiveGuardsErrorIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey :: Unique @@ -2095,27 +2102,29 @@ wildCardKey = mkPreludeMiscIdUnique 0 -- See Note [WildCard absentErrorIdKey = mkPreludeMiscIdUnique 1 augmentIdKey = mkPreludeMiscIdUnique 2 appendIdKey = mkPreludeMiscIdUnique 3 -buildIdKey = mkPreludeMiscIdUnique 4 -errorIdKey = mkPreludeMiscIdUnique 5 -foldrIdKey = mkPreludeMiscIdUnique 6 -recSelErrorIdKey = mkPreludeMiscIdUnique 7 -seqIdKey = mkPreludeMiscIdUnique 8 -absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 9 -eqStringIdKey = mkPreludeMiscIdUnique 10 -noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 11 -nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 12 -runtimeErrorIdKey = mkPreludeMiscIdUnique 13 -patErrorIdKey = mkPreludeMiscIdUnique 14 -realWorldPrimIdKey = mkPreludeMiscIdUnique 15 -recConErrorIdKey = mkPreludeMiscIdUnique 16 -unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 17 -unpackCStringAppendIdKey = mkPreludeMiscIdUnique 18 -unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 19 -unpackCStringIdKey = mkPreludeMiscIdUnique 20 -voidPrimIdKey = mkPreludeMiscIdUnique 21 -typeErrorIdKey = mkPreludeMiscIdUnique 22 -divIntIdKey = mkPreludeMiscIdUnique 23 -modIntIdKey = mkPreludeMiscIdUnique 24 +elemIdKey = mkPreludeMiscIdUnique 4 +buildIdKey = mkPreludeMiscIdUnique 5 +errorIdKey = mkPreludeMiscIdUnique 6 +foldrIdKey = mkPreludeMiscIdUnique 7 +recSelErrorIdKey = mkPreludeMiscIdUnique 8 +seqIdKey = mkPreludeMiscIdUnique 9 +absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 10 +eqStringIdKey = mkPreludeMiscIdUnique 11 +noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 12 +nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 13 +runtimeErrorIdKey = mkPreludeMiscIdUnique 14 +patErrorIdKey = mkPreludeMiscIdUnique 15 +realWorldPrimIdKey = mkPreludeMiscIdUnique 16 +recConErrorIdKey = mkPreludeMiscIdUnique 17 +unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 18 +unpackCStringAppendIdKey = mkPreludeMiscIdUnique 19 +unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 20 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 21 +unpackCStringIdKey = mkPreludeMiscIdUnique 22 +voidPrimIdKey = mkPreludeMiscIdUnique 23 +typeErrorIdKey = mkPreludeMiscIdUnique 24 +divIntIdKey = mkPreludeMiscIdUnique 25 +modIntIdKey = mkPreludeMiscIdUnique 26 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1618,7 +1618,11 @@ iShiftRL# :: Int# -> Int# -> Int# a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# | otherwise = a `uncheckedIShiftRL#` b +------------------------------------------------------------------------ -- Rules for C strings (the functions themselves are now in GHC.CString) +------------------------------------------------------------------------ + +-- Ascii variants {-# RULES "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a @@ -1628,3 +1632,14 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n #-} + +-- Utf8 variants +{-# RULES +"unpackUtf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-listUtf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-appendUtf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + +-- There's a built-in rule (in PrelRules.hs) for +-- unpackFoldrUtf8 "föö" c (unpackFoldrUtf8 "bäz" c n) = unpackFoldrUtf8 "fööbäz" c n + + #-} ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,9 +1149,10 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" [2] forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} + #endif -- | 'notElem' is the negation of 'elem'. @@ -1174,7 +1175,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" [2] forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -9,6 +9,13 @@ * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: Strict IO variants of `hGetContents`, `getContents`, and `readFile`. + * Add rules `unpackUtf8`, `unpack-listUtf8` and `unpack-appendUtf8` to `GHC.Base`. + They correspond to their ascii versions and hopefully make it easier + to handle utf8 encoded strings efficiently. + + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement as expected. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,17 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques + # We only grep for specific patterns to minimize failures when eg core syntax changes + # We expect two unfolds using eqChar + echo $$(cat T17752.dump-simpl | grep unpackFoldrCString) + echo $$(cat T17752.dump-simpl | grep eqChar) + # And two pattern matches + echo $$(cat T17752.dump-simpl | grep "case x1" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,82 @@ +module T17752 where + +-- Should compile to unfoldCStr if the rules fire +isElemLit x = x `elem` "theQuickShinyGHCJumpsOverTheRuleRecursion" +isNotElemLit x = x `notElem` "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion" + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +{- + +Should the grep tests fail make sure the core still behaves +like the one below (or better!) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isElemLit1 = "theQuickShinyGHCJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 20, types: 9, coercions: 0, joins: 0/0} +isElemLit + = \ x -> + unpackFoldrCString# + isElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isNotElemLit1 + = "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 25, types: 10, coercions: 0, joins: 0/0} +isNotElemLit + = \ x -> + case unpackFoldrCString# + isNotElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + of { + False -> True; + True -> False + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'a'# -> True; + 'b'# -> True; + 'c'# -> True + } + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isNotElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'x'# -> True; + 'y'# -> True; + 'z'# -> True + } + } +-} ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,25 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) +GHC.CString.unpackFoldrCString# + case GHC.CString.unpackFoldrCString# +case GHC.Prim.eqChar# x1 y1 of { + case GHC.Prim.eqChar# x1 y1 of { +case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) \ No newline at end of file ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,8 +17,14 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types @@ -71,8 +77,22 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [NOINLINE for unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n +At one stage I had NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. BUT there may be a lot of +literal strings, and making a separate 'unpack' loop for +each is highly gratuitous. See nofib/real/anna/PrettyPrint. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +109,32 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. +If we use the offset start off with the increment and an addition +to get the real address. Which might not be optimized aways. + + Note [Compiling `elem` on Strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The pattern f c = c `elem` "" is quite common in +parsers and often performance critical. + +The fastest way to process this pattern is to transform it +into a case. That is we transform: + + x `elem` "xy" +=> + case x of + 'x' -> True + 'y' -> True + _ -> False + +For this reason there is a BUILTIN rule "ElemLitString" which +performs this rewrite early in the pipeline in case the string +is known and not excessively long. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +157,27 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- See Note [NOINLINE for unpackFoldrCString] +-- {-# INLINE[0] unpackFoldrCString2# #-} +-- unpackFoldrCString2# :: Addr# -> (Char -> a -> a) -> a -> a +-- unpackFoldrCString2# addr f z +-- | isTrue# (ch `eqChar#` '\0'#) = z +-- | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- where +-- -- See Note [unpackCString# iterating over addr] +-- !ch = indexCharOffAddr# addr 0# -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +{-# INLINE[0] unpackFoldrCString# #-} +-- {-# NOINLINE unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +185,44 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [NOINLINE for unpackFoldrCString] +-- {-# INLINE[0] unpackFoldrCString# #-} +{-# INLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +241,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explizit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,13 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22b9504c13276f92e308cbdd190b8378091dfd91 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22b9504c13276f92e308cbdd190b8378091dfd91 You're receiving 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 3 19:29:38 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 15:29:38 -0400 Subject: [Git][ghc/ghc][wip/T17978] WIP: Types for joined traversal Message-ID: <5e878ea2c7e05_61673f8199536d9428540b5@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T17978 at Glasgow Haskell Compiler / GHC Commits: 7942a275 by Simon Jakobi at 2020-04-03T21:27:33+02:00 WIP: Types for joined traversal - - - - - 1 changed file: - compiler/GHC/Stg/DepAnal.hs Changes: ===================================== compiler/GHC/Stg/DepAnal.hs ===================================== @@ -4,7 +4,7 @@ module GHC.Stg.DepAnal (depSortStgPgm) where import GhcPrelude -import GHC.Stg.FVs +import GHC.Core ( Tickish(Breakpoint) ) import GHC.Stg.Syntax import GHC.Types.Id import GHC.Types.Name (Name, nameIsLocalOrFrom) @@ -13,9 +13,14 @@ import Outputable import GHC.Types.Unique.Set (nonDetEltsUniqSet) import GHC.Types.Var.Set import GHC.Types.Module (Module) +import Util + +import Data.Maybe ( mapMaybe ) import Data.Graph (SCC (..)) + + -------------------------------------------------------------------------------- -- * Dependency analysis @@ -25,7 +30,27 @@ type BVs = VarSet -- | Set of free variables type FVs = VarSet --- | Dependency analysis on STG terms. +newtype Env + = Env + { locals :: IdSet + } + +emptyEnv :: Env +emptyEnv = Env emptyVarSet + +addLocals :: [Id] -> Env -> Env +addLocals bndrs env + = env { locals = extendVarSetList (locals env) bndrs } + +-- | This makes sure that only local, non-global free vars make it into the set. +mkFreeVarSet :: Env -> [Id] -> DIdSet +mkFreeVarSet env = mkDVarSet . filter (`elemVarSet` locals env) + +boundIds :: StgBinding -> [Id] +boundIds (StgNonRec b _) = [b] +boundIds (StgRec pairs) = map fst pairs + +-- | Dependency analysis and free variable annotations on STG terms. -- -- Dependencies of a binding are just free variables in the binding. This -- includes imported ids and ids in the current module. For recursive groups we @@ -44,14 +69,95 @@ annTopBindingsDeps this_mod bs = map top_bind bs (StgTopStringLit id bs, emptyVarSet) top_bind (StgTopLifted bs) = - (StgTopLifted (annBindingFreeVars bs), binding emptyVarSet bs) + (StgTopLifted bs', fvs) + where + (bs', _dIdSet, fvs) = binding emptyEnv emptyDVarSet emptyVarSet bs + + binding :: Env -> DIdSet -> BVs -> StgBinding -> (CgStgBinding, DIdSet, FVs) + binding = undefined rhs + + rhs :: Env -> BVs -> StgRhs -> (CgStgRhs, DIdSet, FVs) + rhs = undefined args expr - binding :: BVs -> StgBinding -> FVs - binding bounds (StgNonRec _ r) = - rhs bounds r - binding bounds (StgRec bndrs) = - unionVarSets $ - map (bind_non_rec (extendVarSetList bounds (map fst bndrs))) bndrs + expr :: Env -> DIdSet -> BVs -> StgExpr -> (CgStgBinding, DIdSet, FVs) + expr = undefined alts var expr + + alts :: Env -> BVs -> [StgAlt] -> ([CgStgAlt], DIdSet, FVs) + alts = undefined expr + + args :: Env -> BVs -> [StgArg] -> (DIdSet, FVs) + args = undefined var + + var :: Env -> BVs -> Var -> (DIdSet, FVs) + var = undefined this_mod + +{- + binding :: Env -> DIdSet -> BVs -> StgBinding -> (CgStgBinding, DIdSet, FVs) + binding env body_fv bounds (StgNonRec bndr r) = + (StgNonRec bndr r', fvs, rhs bounds r) + where + -- See Note [Tracking local binders] + (r', rhs_fvs) = rhsFV env r + fvs = delDVarSet body_fv bndr `unionDVarSet` rhs_fvs + + binding env body_fv bounds (StgRec pairs) = + ( StgRec pairs' + , fvs + , unionVarSets $ + map (bind_non_rec (extendVarSetList bounds (map fst pairs))) pairs) + where + -- See Note [Tracking local binders] + bndrs = map fst pairs + (rhss, rhs_fvss) = mapAndUnzip (rhsFV env . snd) pairs + pairs' = zip bndrs rhss + fvs = delDVarSetList (unionDVarSets (body_fv:rhs_fvss)) bndrs + + rhsFV :: Env -> StgRhs -> (CgStgRhs, DIdSet) + rhsFV env (StgRhsClosure _ ccs uf bndrs body) + = (StgRhsClosure fvs ccs uf bndrs body', fvs) + where + -- See Note [Tracking local binders] + (body', body_fvs) = exprFV (addLocals bndrs env) body + fvs = delDVarSetList body_fvs bndrs + rhsFV env (StgRhsCon ccs dc as) = (StgRhsCon ccs dc as, argsFV env as) + + exprFV :: Env -> StgExpr -> (CgStgExpr, DIdSet) + exprFV env = go + where + go (StgApp occ as) + = (StgApp occ as, unionDVarSet (argsFV env as) (mkFreeVarSet env [occ])) + go (StgLit lit) = (StgLit lit, emptyDVarSet) + go (StgConApp dc as tys) = (StgConApp dc as tys, argsFV env as) + go (StgOpApp op as ty) = (StgOpApp op as ty, argsFV env as) + go StgLam{} = pprPanic "StgFVs: StgLam" empty + go (StgCase scrut bndr ty alts) = (StgCase scrut' bndr ty alts', fvs) + where + (scrut', scrut_fvs) = go scrut + -- See Note [Tracking local binders] + (alts', alt_fvss) = mapAndUnzip (altFV (addLocals [bndr] env)) alts + alt_fvs = unionDVarSets alt_fvss + fvs = delDVarSet (unionDVarSet scrut_fvs alt_fvs) bndr + go (StgLet ext bind body) = go_bind (StgLet ext) bind body + go (StgLetNoEscape ext bind body) = go_bind (StgLetNoEscape ext) bind body + go (StgTick tick e) = (StgTick tick e', fvs') + where + (e', fvs) = go e + fvs' = unionDVarSet (tickish tick) fvs + tickish (Breakpoint _ ids) = mkDVarSet ids + tickish _ = emptyDVarSet + + go_bind dc bind body = (dc bind' body', fvs) + where + -- See Note [Tracking local binders] + env' = addLocals (boundIds bind) env + (body', body_fvs) = exprFV env' body + (bind', fvs, _) = binding env' body_fvs bind + + argsFV :: Env -> [StgArg] -> DIdSet + argsFV env = mkFreeVarSet env . mapMaybe f + where + f (StgVarArg occ) = Just occ + f _ = Nothing bind_non_rec :: BVs -> (Id, StgRhs) -> FVs bind_non_rec bounds (_, r) = @@ -112,6 +218,14 @@ annTopBindingsDeps this_mod bs = map top_bind bs alt bounds (_, bndrs, e) = expr (extendVarSetList bounds bndrs) e + altFV :: Env -> StgAlt -> (CgStgAlt, DIdSet) + altFV env (con, bndrs, e) = ((con, bndrs, e'), fvs) + where + -- See Note [Tracking local binders] + (e', rhs_fvs) = exprFV (addLocals bndrs env) e + fvs = delDVarSetList rhs_fvs bndrs +-} + -------------------------------------------------------------------------------- -- * Dependency sorting View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7942a275a9b434b6851c0da2b3512fd6d5a85486 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7942a275a9b434b6851c0da2b3512fd6d5a85486 You're receiving 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 3 22:57:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 03 Apr 2020 18:57:36 -0400 Subject: [Git][ghc/ghc][wip/run-mode] ghc: Introduce --run mode Message-ID: <5e87bf60c02d7_61673f81bb9e8b0428745ba@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/run-mode at Glasgow Haskell Compiler / GHC Commits: bffce3fd by Ben Gamari at 2020-04-03T18:57:29-04:00 ghc: Introduce --run mode As described in #18011, this - - - - - 6 changed files: - docs/users_guide/using.rst - ghc/Main.hs - + testsuite/tests/driver/RunMode.hs - + testsuite/tests/driver/RunMode.stdout - + testsuite/tests/driver/RunMode/Test.hs - testsuite/tests/driver/all.T Changes: ===================================== docs/users_guide/using.rst ===================================== @@ -265,6 +265,17 @@ The available mode flags are: Interactive mode, which is also available as :program:`ghci`. Interactive mode is described in more detail in :ref:`ghci`. +.. ghc-flag:: --run + :shortdesc: Run a Haskell program. + :type: mode + :category: modes + + .. index:: + single: run mode + single: GHCi + + Run a script's ``main`` binding using the bytecode interpreter. + .. ghc-flag:: --make :shortdesc: Build a multi-module Haskell program, automatically figuring out dependencies. Likely to be much easier, and faster, than using ===================================== ghc/Main.hs ===================================== @@ -161,6 +161,7 @@ main' postLoadMode dflags0 args flagWarnings = do = case postLoadMode of DoInteractive -> (CompManager, HscInterpreted, LinkInMemory) DoEval _ -> (CompManager, HscInterpreted, LinkInMemory) + DoRun -> (CompManager, HscInterpreted, LinkInMemory) DoMake -> (CompManager, dflt_target, LinkBinary) DoBackpack -> (CompManager, dflt_target, LinkBinary) DoMkDependHS -> (MkDepend, dflt_target, LinkBinary) @@ -172,6 +173,7 @@ main' postLoadMode dflags0 args flagWarnings = do ghcLink = link, verbosity = case postLoadMode of DoEval _ -> 0 + DoRun -> 0 _other -> 1 } @@ -185,6 +187,7 @@ main' postLoadMode dflags0 args flagWarnings = do -- a great story for the moment. dflags2 | DoInteractive <- postLoadMode = def_ghci_flags | DoEval _ <- postLoadMode = def_ghci_flags + | DoRun <- postLoadMode = def_ghci_flags | otherwise = dflags1 where def_ghci_flags = dflags1 `gopt_set` Opt_ImplicitImportQualified `gopt_set` Opt_IgnoreOptimChanges @@ -271,6 +274,7 @@ main' postLoadMode dflags0 args flagWarnings = do DoInteractive -> ghciUI hsc_env dflags6 srcs Nothing DoEval exprs -> ghciUI hsc_env dflags6 srcs $ Just $ reverse exprs + DoRun -> ghciUI hsc_env dflags6 srcs (Just ["main"]) DoAbiHash -> abiHash (map fst srcs) ShowPackages -> liftIO $ showPackages dflags6 DoFrontend f -> doFrontend f srcs @@ -488,15 +492,17 @@ data PostLoadMode | DoBackpack -- ghc --backpack foo.bkp | DoInteractive -- ghc --interactive | DoEval [String] -- ghc -e foo -e bar => DoEval ["bar", "foo"] + | DoRun -- ghc --run | DoAbiHash -- ghc --abi-hash | ShowPackages -- ghc --show-packages | DoFrontend ModuleName -- ghc --frontend Plugin.Module -doMkDependHSMode, doMakeMode, doInteractiveMode, +doMkDependHSMode, doMakeMode, doInteractiveMode, doRunMode, doAbiHashMode, showPackagesMode :: Mode doMkDependHSMode = mkPostLoadMode DoMkDependHS doMakeMode = mkPostLoadMode DoMake doInteractiveMode = mkPostLoadMode DoInteractive +doRunMode = mkPostLoadMode DoRun doAbiHashMode = mkPostLoadMode DoAbiHash showPackagesMode = mkPostLoadMode ShowPackages @@ -557,11 +563,13 @@ needsInputsMode _ = False isLinkMode :: PostLoadMode -> Bool isLinkMode (StopBefore StopLn) = True isLinkMode DoMake = True +isLinkMode DoRun = True isLinkMode DoInteractive = True isLinkMode (DoEval _) = True isLinkMode _ = False isCompManagerMode :: PostLoadMode -> Bool +isCompManagerMode DoRun = True isCompManagerMode DoMake = True isCompManagerMode DoInteractive = True isCompManagerMode (DoEval _) = True @@ -643,6 +651,7 @@ mode_flags = , defFlag "E" (PassFlag (setMode (stopBeforeMode anyHsc))) , defFlag "C" (PassFlag (setMode (stopBeforeMode HCc))) , defFlag "S" (PassFlag (setMode (stopBeforeMode (As False)))) + , defFlag "-run" (PassFlag (setMode doRunMode)) , defFlag "-make" (PassFlag (setMode doMakeMode)) , defFlag "-backpack" (PassFlag (setMode doBackpackMode)) , defFlag "-interactive" (PassFlag (setMode doInteractiveMode)) ===================================== testsuite/tests/driver/RunMode.hs ===================================== @@ -0,0 +1,4 @@ +import Test + +main :: IO () +main = test ===================================== testsuite/tests/driver/RunMode.stdout ===================================== @@ -0,0 +1 @@ +hello ===================================== testsuite/tests/driver/RunMode/Test.hs ===================================== @@ -0,0 +1,4 @@ +module Test where + +test :: IO () +test = putStrLn "hello" ===================================== testsuite/tests/driver/all.T ===================================== @@ -279,3 +279,4 @@ test('T16737', test('T17143', exit_code(1), run_command, ['{compiler} T17143.hs -S -fno-code']) test('T17786', unless(opsys('mingw32'), skip), makefile_test, []) +test('RunMode', extra_files(['RunMode/Test.hs']), run_command, ['{compiler} --run -iRunMode/ -ignore-dot-ghci RunMode.hs']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bffce3fda867c9736dd4c07f60b004047fbdf5a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bffce3fda867c9736dd4c07f60b004047fbdf5a2 You're receiving 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 3 23:02:57 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 03 Apr 2020 19:02:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/dwarf-bindists Message-ID: <5e87c0a1f0ad2_61673f81bb9e8b04287767b@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/dwarf-bindists at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/dwarf-bindists You're receiving 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 3 23:07:56 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 03 Apr 2020 19:07:56 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e87c1cc987a4_616713503ee028792ea@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: a4a056b1 by Ben Gamari at 2020-04-03T19:03:42-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Metric Decrease: T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 9 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1001,10 +1001,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1023,6 +1019,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1306,8 +1318,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1552,14 +1563,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1568,8 +1574,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3021,8 +3019,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,73 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a4a056b13e4ed9c3721143d205d8920be47e475b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a4a056b13e4ed9c3721143d205d8920be47e475b You're receiving 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 3 23:10:10 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 03 Apr 2020 19:10:10 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e87c252feb0_61673f8199536d9428814ed@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: 9d7a4879 by Ben Gamari at 2020-04-03T19:10:01-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 10 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/plugins/all.T - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1001,10 +1001,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1023,6 +1019,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1306,8 +1318,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1552,14 +1563,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1568,8 +1574,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3021,8 +3019,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,73 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/plugins/all.T ===================================== @@ -167,7 +167,6 @@ test('plugin-recomp-flags', test('plugin-recomp-change', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}') ], makefile_test, []) @@ -175,7 +174,6 @@ test('plugin-recomp-change', test('plugin-recomp-change-prof', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}'), when(not config.have_profiling,skip) ], ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d7a48790cd9188edf88a32ecc96a0ecd459a79b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d7a48790cd9188edf88a32ecc96a0ecd459a79b You're receiving 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 4 00:56:23 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 20:56:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/refactor_cmm_weights Message-ID: <5e87db374dfa4_61673f81bb9e8b042893346@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/refactor_cmm_weights You're receiving 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 4 01:17:56 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 21:17:56 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5e87e04477a20_61673f8198ee100c2896282@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: adb19221 by Andreas Klebinger at 2020-04-04T03:17:20+02:00 Refactor linear reg alloc to remember past assignments. We used to pick the first free register, which is damn fast but produces fixup blocks on the regular. Now we look for past assignments first. This means for loops with blocks A, B, C if a variable is live in A & C we will pick the right register (if available) in C. This avoids some needless fixup blocks. - - - - - 12 changed files: - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs - compiler/GHC/CmmToAsm/Reg/Linear/State.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs - compiler/utils/Outputable.hs Changes: ===================================== compiler/GHC/Cmm/Pipeline.hs ===================================== @@ -116,6 +116,10 @@ cpsTop hsc_env proc = condPass Opt_CmmSink (cmmSink dflags) g Opt_D_dump_cmm_sink "Sink assignments" + g <- {-# SCC "sink" #-} -- See Note [Sinking after stack layout] + condPass Opt_CmmSink (cmmSink dflags) g + Opt_D_dump_cmm_sink "Sink assignments" + ------------- CAF analysis ---------------------------------------------- let cafEnv = {-# SCC "cafAnal" #-} cafAnal call_pps l g dumpWith dflags Opt_D_dump_cmm_caf "CAFEnv" FormatText (ppr cafEnv) ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -639,7 +639,8 @@ sequenceChain _info _weights [x] = [x] sequenceChain info weights' blocks@((BasicBlock entry _):_) = let weights :: CFG weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' + -- cfg' + weights' where (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' cfg' = {-# SCC rewriteEdges #-} ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,20 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG weights proc@(CmmProc _info _lab _live graph) cfg = + staticPredCfg (g_entry graph) . optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +758,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +946,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,12 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +252,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +287,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +331,20 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + assig <- getBlockAssigR + + -- pprTraceM "assignment" $ ppr assig (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +380,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +407,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are love on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> BlockId -- ^ the id of the current block, for debugging @@ -476,7 +487,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,7 +497,9 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform + block_assig <- getBlockAssigR case regUsageOfInstr platform instr of { RU read written -> do let real_written = [ rr | (RegReal rr) <- written ] @@ -525,10 +538,12 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. - -- when (not $ null fixup_blocks) $ - -- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) +-- when (not $ null fixup_blocks) $ +-- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) -- (e) Delete all register assignments for temps which are read -- (only) and die here. Update the free register list. @@ -737,7 +752,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +764,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +795,15 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +findVirtRegAny :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe Loc) +findVirtRegAny vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe Loc -> Maybe Loc + findVirtRegAssig assig z = + lookupUFM (snd assig) vreg <|> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -801,7 +826,12 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc -- case (2): we have a free register (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + do _r <- findVirtRegAny r + my_reg <- return $ case _r of + Just (InReg my_reg) -> my_reg + _ -> my_reg + -- pprTraceM "findVirtRegAny" $ ppr (my_reg, _r) + spills' <- loadTemp r spill_loc my_reg spills setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) setFreeRegsR $ frAllocateReg platform my_reg freeRegs ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -138,6 +138,9 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + -- | Map virtual regs to regs they have been assigned in the past. + , ra_sugg_assig :: RegMap Loc } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} @@ -52,7 +53,9 @@ import GHC.Cmm.BlockId import GHC.Platform import GHC.Types.Unique import GHC.Types.Unique.Supply +import GHC.Types.Unique.FM +import Control.Applicative import Control.Monad (ap) -- Avoids using unboxed tuples when loading into GHCi @@ -111,7 +114,8 @@ runR config block_assig freeregs assig stack us thing = , ra_us = us , ra_spills = [] , ra_config = config - , ra_fixups = [] }) + , ra_fixups = [] + , ra_sugg_assig = assig }) of RA_Result state returned_thing -> (ra_blockassig state, ra_stack state, makeRAStats state, returned_thing) @@ -157,6 +161,24 @@ setAssigR :: RegMap Loc -> RegM freeRegs () setAssigR assig = RegM $ \ s -> RA_Result s{ra_assig=assig} () +findVirtRegAny :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe Loc) +findVirtRegAny vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe Loc -> Maybe Loc + findVirtRegAssig assig z = + lookupUFM (snd assig) vreg <|> z + +-- suggestAssig :: RegMap Loc -> RegM () +-- suggestAssig assig = RegM $ \ s -> +-- RA_Result s{ra_sugg_assig=plusUFM (ra_sugg_assig s) assig} () + +-- getSug :: Unique -> RegM Loc +-- getSug = RegM $ \ s at RA_State{ra_sugg_assig = sugg_assig} -> +-- RA_Result s sugg_assig + getBlockAssigR :: RegM freeRegs (BlockAssignment freeRegs) getBlockAssigR = RegM $ \ s at RA_State{ra_blockassig = assig} -> RA_Result s assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/utils/Outputable.hs ===================================== @@ -847,6 +847,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/adb19221a764d1872c79e8b32aade0d897a33314 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/adb19221a764d1872c79e8b32aade0d897a33314 You're receiving 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 4 01:39:14 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 03 Apr 2020 21:39:14 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5e87e54293598_61673f8199536d94289815c@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: a8e74bc9 by Andreas Klebinger at 2020-04-04T03:39:00+02:00 Refactor linear reg alloc to remember past assignments. We used to pick the first free register, which is damn fast but produces fixup blocks on the regular. Now we look for past assignments first. This means for loops with blocks A, B, C if a variable is live in A & C we will pick the right register (if available) in C. This avoids some needless fixup blocks. - - - - - 12 changed files: - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs - compiler/GHC/CmmToAsm/Reg/Linear/State.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs - compiler/utils/Outputable.hs Changes: ===================================== compiler/GHC/Cmm/Pipeline.hs ===================================== @@ -116,6 +116,10 @@ cpsTop hsc_env proc = condPass Opt_CmmSink (cmmSink dflags) g Opt_D_dump_cmm_sink "Sink assignments" + g <- {-# SCC "sink" #-} -- See Note [Sinking after stack layout] + condPass Opt_CmmSink (cmmSink dflags) g + Opt_D_dump_cmm_sink "Sink assignments" + ------------- CAF analysis ---------------------------------------------- let cafEnv = {-# SCC "cafAnal" #-} cafAnal call_pps l g dumpWith dflags Opt_D_dump_cmm_caf "CAFEnv" FormatText (ppr cafEnv) ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -639,7 +639,8 @@ sequenceChain _info _weights [x] = [x] sequenceChain info weights' blocks@((BasicBlock entry _):_) = let weights :: CFG weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' + -- cfg' + weights' where (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' cfg' = {-# SCC rewriteEdges #-} ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,20 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG weights proc@(CmmProc _info _lab _live graph) cfg = + staticPredCfg (g_entry graph) . optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +758,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +946,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,12 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +252,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +287,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +331,20 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + assig <- getBlockAssigR + + -- pprTraceM "assignment" $ ppr assig (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +380,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +407,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are love on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> BlockId -- ^ the id of the current block, for debugging @@ -476,7 +487,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,7 +497,9 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform + block_assig <- getBlockAssigR case regUsageOfInstr platform instr of { RU read written -> do let real_written = [ rr | (RegReal rr) <- written ] @@ -525,10 +538,12 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. - -- when (not $ null fixup_blocks) $ - -- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) +-- when (not $ null fixup_blocks) $ +-- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) -- (e) Delete all register assignments for temps which are read -- (only) and die here. Update the free register list. @@ -737,7 +752,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +764,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +795,15 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +findVirtRegAny :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe Loc) +findVirtRegAny vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe Loc -> Maybe Loc + findVirtRegAssig assig z = + lookupUFM (snd assig) vreg <|> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,13 +820,20 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] case freeRegs_thisClass of -- case (2): we have a free register (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + do _r <- findVirtRegAny r + -- pprTraceM "free" $ ppr (_r, my_reg, freeRegs_thisClass) + my_reg <- return $ case _r of + Just (InReg my_reg') + | my_reg' `elem` freeRegs_thisClass -> my_reg' + _ -> my_reg :: RealReg + -- pprTraceM "findVirtRegAny" $ ppr (my_reg, _r) + spills' <- loadTemp r spill_loc my_reg spills setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) setFreeRegsR $ frAllocateReg platform my_reg freeRegs ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -138,6 +138,9 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + -- | Map virtual regs to regs they have been assigned in the past. + , ra_sugg_assig :: RegMap Loc } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} @@ -52,7 +53,9 @@ import GHC.Cmm.BlockId import GHC.Platform import GHC.Types.Unique import GHC.Types.Unique.Supply +import GHC.Types.Unique.FM +import Control.Applicative import Control.Monad (ap) -- Avoids using unboxed tuples when loading into GHCi @@ -111,7 +114,8 @@ runR config block_assig freeregs assig stack us thing = , ra_us = us , ra_spills = [] , ra_config = config - , ra_fixups = [] }) + , ra_fixups = [] + , ra_sugg_assig = assig }) of RA_Result state returned_thing -> (ra_blockassig state, ra_stack state, makeRAStats state, returned_thing) @@ -157,6 +161,24 @@ setAssigR :: RegMap Loc -> RegM freeRegs () setAssigR assig = RegM $ \ s -> RA_Result s{ra_assig=assig} () +findVirtRegAny :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe Loc) +findVirtRegAny vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe Loc -> Maybe Loc + findVirtRegAssig assig z = + lookupUFM (snd assig) vreg <|> z + +-- suggestAssig :: RegMap Loc -> RegM () +-- suggestAssig assig = RegM $ \ s -> +-- RA_Result s{ra_sugg_assig=plusUFM (ra_sugg_assig s) assig} () + +-- getSug :: Unique -> RegM Loc +-- getSug = RegM $ \ s at RA_State{ra_sugg_assig = sugg_assig} -> +-- RA_Result s sugg_assig + getBlockAssigR :: RegM freeRegs (BlockAssignment freeRegs) getBlockAssigR = RegM $ \ s at RA_State{ra_blockassig = assig} -> RA_Result s assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/utils/Outputable.hs ===================================== @@ -847,6 +847,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a8e74bc95970f2c2f6b8c2d1821d11fefdb2eb37 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a8e74bc95970f2c2f6b8c2d1821d11fefdb2eb37 You're receiving 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 4 02:40:23 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 22:40:23 -0400 Subject: [Git][ghc/ghc][wip/T17978] 9 commits: WIP Message-ID: <5e87f39787040_616766534602898439@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T17978 at Glasgow Haskell Compiler / GHC Commits: cbe92c8a by Simon Jakobi at 2020-04-03T22:00:03+02:00 WIP - - - - - b3784f5a by Simon Jakobi at 2020-04-03T22:21:28+02:00 WIP: binding done - - - - - fb1e2246 by Simon Jakobi at 2020-04-03T22:52:34+02:00 WIP: rhs done - - - - - ed60a060 by Simon Jakobi at 2020-04-04T02:01:09+02:00 WIP: alt done, parts of expr - - - - - 90064760 by Simon Jakobi at 2020-04-04T02:17:21+02:00 WIP: alts mostly - - - - - bb7c370e by Simon Jakobi at 2020-04-04T03:12:34+02:00 WIP: StgLet done - - - - - 73f83372 by Simon Jakobi at 2020-04-04T03:20:06+02:00 WIP: expr done - - - - - a84b23aa by Simon Jakobi at 2020-04-04T04:30:23+02:00 WIP: args done - - - - - 5b623bad by Simon Jakobi at 2020-04-04T04:39:41+02:00 Small refactoring - - - - - 1 changed file: - compiler/GHC/Stg/DepAnal.hs Changes: ===================================== compiler/GHC/Stg/DepAnal.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Types.Var.Set import GHC.Types.Module (Module) import Util -import Data.Maybe ( mapMaybe ) +import Data.Maybe ( catMaybes ) import Data.Graph (SCC (..)) @@ -46,10 +46,6 @@ addLocals bndrs env mkFreeVarSet :: Env -> [Id] -> DIdSet mkFreeVarSet env = mkDVarSet . filter (`elemVarSet` locals env) -boundIds :: StgBinding -> [Id] -boundIds (StgNonRec b _) = [b] -boundIds (StgRec pairs) = map fst pairs - -- | Dependency analysis and free variable annotations on STG terms. -- -- Dependencies of a binding are just free variables in the binding. This @@ -73,102 +69,126 @@ annTopBindingsDeps this_mod bs = map top_bind bs where (bs', _dIdSet, fvs) = binding emptyEnv emptyDVarSet emptyVarSet bs - binding :: Env -> DIdSet -> BVs -> StgBinding -> (CgStgBinding, DIdSet, FVs) - binding = undefined rhs - - rhs :: Env -> BVs -> StgRhs -> (CgStgRhs, DIdSet, FVs) - rhs = undefined args expr - - expr :: Env -> DIdSet -> BVs -> StgExpr -> (CgStgBinding, DIdSet, FVs) - expr = undefined alts var expr - - alts :: Env -> BVs -> [StgAlt] -> ([CgStgAlt], DIdSet, FVs) - alts = undefined expr - - args :: Env -> BVs -> [StgArg] -> (DIdSet, FVs) - args = undefined var - - var :: Env -> BVs -> Var -> (DIdSet, FVs) - var = undefined this_mod - -{- binding :: Env -> DIdSet -> BVs -> StgBinding -> (CgStgBinding, DIdSet, FVs) binding env body_fv bounds (StgNonRec bndr r) = - (StgNonRec bndr r', fvs, rhs bounds r) + (StgNonRec bndr r', fvs, da_fvs) where -- See Note [Tracking local binders] - (r', rhs_fvs) = rhsFV env r + (r', rhs_fvs, da_fvs) = rhs env bounds r fvs = delDVarSet body_fv bndr `unionDVarSet` rhs_fvs - - binding env body_fv bounds (StgRec pairs) = - ( StgRec pairs' - , fvs - , unionVarSets $ - map (bind_non_rec (extendVarSetList bounds (map fst pairs))) pairs) + binding env body_fv bounds (StgRec bindings) = + ( StgRec (zip bndrs rhss') + , delDVarSetList (unionDVarSets (body_fv:rhs_fvss)) bndrs + , unionVarSets da_fvss + ) where - -- See Note [Tracking local binders] - bndrs = map fst pairs - (rhss, rhs_fvss) = mapAndUnzip (rhsFV env . snd) pairs - pairs' = zip bndrs rhss - fvs = delDVarSetList (unionDVarSets (body_fv:rhs_fvss)) bndrs - - rhsFV :: Env -> StgRhs -> (CgStgRhs, DIdSet) - rhsFV env (StgRhsClosure _ ccs uf bndrs body) - = (StgRhsClosure fvs ccs uf bndrs body', fvs) + (bndrs, rhss) = unzip bindings + bounds' = extendVarSetList bounds bndrs + (rhss', rhs_fvss, da_fvss) = mapAndUnzip3 (rhs env bounds') rhss + + rhs :: Env -> BVs -> StgRhs -> (CgStgRhs, DIdSet, FVs) + rhs env bounds (StgRhsClosure _ ccs uf bndrs body) = + ( StgRhsClosure fvs ccs uf bndrs body' + , fvs + , da_fvs + ) where - -- See Note [Tracking local binders] - (body', body_fvs) = exprFV (addLocals bndrs env) body + (body', body_fvs, da_fvs) = expr (addLocals bndrs env) (extendVarSetList bounds bndrs) body fvs = delDVarSetList body_fvs bndrs - rhsFV env (StgRhsCon ccs dc as) = (StgRhsCon ccs dc as, argsFV env as) + rhs env bounds (StgRhsCon ccs dc as) = + ( StgRhsCon ccs dc as + , fvs + , da_fvs + ) + where + (fvs, da_fvs) = args env bounds as - exprFV :: Env -> StgExpr -> (CgStgExpr, DIdSet) - exprFV env = go + expr :: Env -> BVs -> StgExpr -> (CgStgExpr, DIdSet, FVs) + expr env = go where - go (StgApp occ as) - = (StgApp occ as, unionDVarSet (argsFV env as) (mkFreeVarSet env [occ])) - go (StgLit lit) = (StgLit lit, emptyDVarSet) - go (StgConApp dc as tys) = (StgConApp dc as tys, argsFV env as) - go (StgOpApp op as ty) = (StgOpApp op as ty, argsFV env as) - go StgLam{} = pprPanic "StgFVs: StgLam" empty - go (StgCase scrut bndr ty alts) = (StgCase scrut' bndr ty alts', fvs) + go bounds (StgApp occ as) = + ( StgApp occ as + , unionDVarSet fvs (mkFreeVarSet env [occ]) + , var bounds occ `unionVarSet` da_fvs + ) + where + (fvs, da_fvs) = args env bounds as + go _ (StgLit lit) = + (StgLit lit, emptyDVarSet, emptyVarSet) + go bounds (StgConApp dc as tys) = + (StgConApp dc as tys, fvs, da_fvs) + where + (fvs, da_fvs) = args env bounds as + go bounds (StgOpApp op as ty) = + (StgOpApp op as ty, fvs, da_fvs) where - (scrut', scrut_fvs) = go scrut + (fvs, da_fvs) = args env bounds as + go _ lam at StgLam{} = + pprPanic "annTopBindingsDeps" (text "Found lambda:" $$ ppr lam) + go bounds (StgCase scrut bndr ty as) = + ( StgCase scrut' bndr ty alts' + , delDVarSet (unionDVarSet scrut_fvs alt_fvs) bndr + , scrut_da_fvs `unionVarSet` alt_da_fvs + ) + where + (scrut', scrut_fvs, scrut_da_fvs) = go bounds scrut -- See Note [Tracking local binders] - (alts', alt_fvss) = mapAndUnzip (altFV (addLocals [bndr] env)) alts - alt_fvs = unionDVarSets alt_fvss - fvs = delDVarSet (unionDVarSet scrut_fvs alt_fvs) bndr - go (StgLet ext bind body) = go_bind (StgLet ext) bind body - go (StgLetNoEscape ext bind body) = go_bind (StgLetNoEscape ext) bind body - go (StgTick tick e) = (StgTick tick e', fvs') + (alts', alt_fvs, alt_da_fvs) = + alts (addLocals [bndr] env) (extendVarSet bounds bndr) as + go bounds (StgLet ext bind body) = + go_bind bounds (StgLet ext) bind body + go bounds (StgLetNoEscape ext bind body) = + go_bind bounds (StgLetNoEscape ext) bind body + go bounds (StgTick tick e) = + (StgTick tick e', fvs', da_fvs) where - (e', fvs) = go e + (e', fvs, da_fvs) = go bounds e fvs' = unionDVarSet (tickish tick) fvs tickish (Breakpoint _ ids) = mkDVarSet ids tickish _ = emptyDVarSet - - go_bind dc bind body = (dc bind' body', fvs) + + go_bind bounds dc bind body = + ( dc bind' body' + , fvs + , da_bind_fvs `unionVarSet` da_body_fvs + ) where -- See Note [Tracking local binders] - env' = addLocals (boundIds bind) env - (body', body_fvs) = exprFV env' body - (bind', fvs, _) = binding env' body_fvs bind + binders = bindersOf bind + env' = addLocals binders env + (body', body_fvs, da_body_fvs) = + expr env' (extendVarSetList bounds binders) body + (bind', fvs, da_bind_fvs) = binding env' body_fvs bounds bind - argsFV :: Env -> [StgArg] -> DIdSet - argsFV env = mkFreeVarSet env . mapMaybe f + alts :: Env -> BVs -> [StgAlt] -> ([CgStgAlt], DIdSet, FVs) + alts env bounds as = + ( as' + , unionDVarSets alt_fvss + , unionVarSets alt_da_fvss + ) where - f (StgVarArg occ) = Just occ - f _ = Nothing - - bind_non_rec :: BVs -> (Id, StgRhs) -> FVs - bind_non_rec bounds (_, r) = - rhs bounds r + (as', alt_fvss, alt_da_fvss) = mapAndUnzip3 (alt env bounds) as + + alt :: Env -> BVs -> StgAlt -> (CgStgAlt, DIdSet, FVs) + alt env bounds (con, bndrs, e) = + ( (con, bndrs, e') + , delDVarSetList rhs_fvs bndrs + , da_fvs + ) + where + (e', rhs_fvs, da_fvs) = expr (addLocals bndrs env) (extendVarSetList bounds bndrs) e - rhs :: BVs -> StgRhs -> FVs - rhs bounds (StgRhsClosure _ _ _ as e) = - expr (extendVarSetList bounds as) e + args :: Env -> BVs -> [StgArg] -> (DIdSet, FVs) + args env bounds as = + ( mkFreeVarSet env (catMaybes mIds) + , unionVarSets da_fvss + ) + where + (mIds, da_fvss) = mapAndUnzip (arg bounds) as - rhs bounds (StgRhsCon _ _ as) = - args bounds as + arg :: BVs -> StgArg -> (Maybe Id, FVs) + arg bounds (StgVarArg v) = (Just v, var bounds v) + arg _ StgLitArg{} = (Nothing, emptyVarSet) var :: BVs -> Var -> FVs var bounds v @@ -178,54 +198,6 @@ annTopBindingsDeps this_mod bs = map top_bind bs | otherwise = emptyVarSet - arg :: BVs -> StgArg -> FVs - arg bounds (StgVarArg v) = var bounds v - arg _ StgLitArg{} = emptyVarSet - - args :: BVs -> [StgArg] -> FVs - args bounds as = unionVarSets (map (arg bounds) as) - - expr :: BVs -> StgExpr -> FVs - expr bounds (StgApp f as) = - var bounds f `unionVarSet` args bounds as - - expr _ StgLit{} = - emptyVarSet - - expr bounds (StgConApp _ as _) = - args bounds as - expr bounds (StgOpApp _ as _) = - args bounds as - expr _ lam at StgLam{} = - pprPanic "annTopBindingsDeps" (text "Found lambda:" $$ ppr lam) - expr bounds (StgCase scrut scrut_bndr _ as) = - expr bounds scrut `unionVarSet` - alts (extendVarSet bounds scrut_bndr) as - expr bounds (StgLet _ bs e) = - binding bounds bs `unionVarSet` - expr (extendVarSetList bounds (bindersOf bs)) e - expr bounds (StgLetNoEscape _ bs e) = - binding bounds bs `unionVarSet` - expr (extendVarSetList bounds (bindersOf bs)) e - - expr bounds (StgTick _ e) = - expr bounds e - - alts :: BVs -> [StgAlt] -> FVs - alts bounds = unionVarSets . map (alt bounds) - - alt :: BVs -> StgAlt -> FVs - alt bounds (_, bndrs, e) = - expr (extendVarSetList bounds bndrs) e - - altFV :: Env -> StgAlt -> (CgStgAlt, DIdSet) - altFV env (con, bndrs, e) = ((con, bndrs, e'), fvs) - where - -- See Note [Tracking local binders] - (e', rhs_fvs) = exprFV (addLocals bndrs env) e - fvs = delDVarSetList rhs_fvs bndrs --} - -------------------------------------------------------------------------------- -- * Dependency sorting View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7942a275a9b434b6851c0da2b3512fd6d5a85486...5b623bad6f0d4bbf88386cf119a49b09cf1aeca4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7942a275a9b434b6851c0da2b3512fd6d5a85486...5b623bad6f0d4bbf88386cf119a49b09cf1aeca4 You're receiving 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 4 02:48:55 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 22:48:55 -0400 Subject: [Git][ghc/ghc][wip/T17978] Whitespace Message-ID: <5e87f59745e38_6167134ebbc4289882d@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T17978 at Glasgow Haskell Compiler / GHC Commits: 43b239df by Simon Jakobi at 2020-04-04T04:48:41+02:00 Whitespace - - - - - 1 changed file: - compiler/GHC/Stg/DepAnal.hs Changes: ===================================== compiler/GHC/Stg/DepAnal.hs ===================================== @@ -19,8 +19,6 @@ import Data.Maybe ( catMaybes ) import Data.Graph (SCC (..)) - - -------------------------------------------------------------------------------- -- * Dependency analysis View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43b239df23bdd8a58ca353e2eb2492f2634d152a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43b239df23bdd8a58ca353e2eb2492f2634d152a You're receiving 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 4 02:51:25 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 22:51:25 -0400 Subject: [Git][ghc/ghc][wip/T17978] Join the binding traversals Message-ID: <5e87f62d9c8aa_6167134ebbc42899229@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T17978 at Glasgow Haskell Compiler / GHC Commits: 2d489a92 by Simon Jakobi at 2020-04-04T04:51:16+02:00 Join the binding traversals - - - - - 1 changed file: - compiler/GHC/Stg/DepAnal.hs Changes: ===================================== compiler/GHC/Stg/DepAnal.hs ===================================== @@ -4,7 +4,7 @@ module GHC.Stg.DepAnal (depSortStgPgm) where import GhcPrelude -import GHC.Stg.FVs +import GHC.Core ( Tickish(Breakpoint) ) import GHC.Stg.Syntax import GHC.Types.Id import GHC.Types.Name (Name, nameIsLocalOrFrom) @@ -13,6 +13,9 @@ import Outputable import GHC.Types.Unique.Set (nonDetEltsUniqSet) import GHC.Types.Var.Set import GHC.Types.Module (Module) +import Util + +import Data.Maybe ( catMaybes ) import Data.Graph (SCC (..)) @@ -25,7 +28,23 @@ type BVs = VarSet -- | Set of free variables type FVs = VarSet --- | Dependency analysis on STG terms. +newtype Env + = Env + { locals :: IdSet + } + +emptyEnv :: Env +emptyEnv = Env emptyVarSet + +addLocals :: [Id] -> Env -> Env +addLocals bndrs env + = env { locals = extendVarSetList (locals env) bndrs } + +-- | This makes sure that only local, non-global free vars make it into the set. +mkFreeVarSet :: Env -> [Id] -> DIdSet +mkFreeVarSet env = mkDVarSet . filter (`elemVarSet` locals env) + +-- | Dependency analysis and free variable annotations on STG terms. -- -- Dependencies of a binding are just free variables in the binding. This -- includes imported ids and ids in the current module. For recursive groups we @@ -44,25 +63,130 @@ annTopBindingsDeps this_mod bs = map top_bind bs (StgTopStringLit id bs, emptyVarSet) top_bind (StgTopLifted bs) = - (StgTopLifted (annBindingFreeVars bs), binding emptyVarSet bs) - - binding :: BVs -> StgBinding -> FVs - binding bounds (StgNonRec _ r) = - rhs bounds r - binding bounds (StgRec bndrs) = - unionVarSets $ - map (bind_non_rec (extendVarSetList bounds (map fst bndrs))) bndrs - - bind_non_rec :: BVs -> (Id, StgRhs) -> FVs - bind_non_rec bounds (_, r) = - rhs bounds r - - rhs :: BVs -> StgRhs -> FVs - rhs bounds (StgRhsClosure _ _ _ as e) = - expr (extendVarSetList bounds as) e - - rhs bounds (StgRhsCon _ _ as) = - args bounds as + (StgTopLifted bs', fvs) + where + (bs', _dIdSet, fvs) = binding emptyEnv emptyDVarSet emptyVarSet bs + + binding :: Env -> DIdSet -> BVs -> StgBinding -> (CgStgBinding, DIdSet, FVs) + binding env body_fv bounds (StgNonRec bndr r) = + (StgNonRec bndr r', fvs, da_fvs) + where + -- See Note [Tracking local binders] + (r', rhs_fvs, da_fvs) = rhs env bounds r + fvs = delDVarSet body_fv bndr `unionDVarSet` rhs_fvs + binding env body_fv bounds (StgRec bindings) = + ( StgRec (zip bndrs rhss') + , delDVarSetList (unionDVarSets (body_fv:rhs_fvss)) bndrs + , unionVarSets da_fvss + ) + where + (bndrs, rhss) = unzip bindings + bounds' = extendVarSetList bounds bndrs + (rhss', rhs_fvss, da_fvss) = mapAndUnzip3 (rhs env bounds') rhss + + rhs :: Env -> BVs -> StgRhs -> (CgStgRhs, DIdSet, FVs) + rhs env bounds (StgRhsClosure _ ccs uf bndrs body) = + ( StgRhsClosure fvs ccs uf bndrs body' + , fvs + , da_fvs + ) + where + (body', body_fvs, da_fvs) = expr (addLocals bndrs env) (extendVarSetList bounds bndrs) body + fvs = delDVarSetList body_fvs bndrs + rhs env bounds (StgRhsCon ccs dc as) = + ( StgRhsCon ccs dc as + , fvs + , da_fvs + ) + where + (fvs, da_fvs) = args env bounds as + + expr :: Env -> BVs -> StgExpr -> (CgStgExpr, DIdSet, FVs) + expr env = go + where + go bounds (StgApp occ as) = + ( StgApp occ as + , unionDVarSet fvs (mkFreeVarSet env [occ]) + , var bounds occ `unionVarSet` da_fvs + ) + where + (fvs, da_fvs) = args env bounds as + go _ (StgLit lit) = + (StgLit lit, emptyDVarSet, emptyVarSet) + go bounds (StgConApp dc as tys) = + (StgConApp dc as tys, fvs, da_fvs) + where + (fvs, da_fvs) = args env bounds as + go bounds (StgOpApp op as ty) = + (StgOpApp op as ty, fvs, da_fvs) + where + (fvs, da_fvs) = args env bounds as + go _ lam at StgLam{} = + pprPanic "annTopBindingsDeps" (text "Found lambda:" $$ ppr lam) + go bounds (StgCase scrut bndr ty as) = + ( StgCase scrut' bndr ty alts' + , delDVarSet (unionDVarSet scrut_fvs alt_fvs) bndr + , scrut_da_fvs `unionVarSet` alt_da_fvs + ) + where + (scrut', scrut_fvs, scrut_da_fvs) = go bounds scrut + -- See Note [Tracking local binders] + (alts', alt_fvs, alt_da_fvs) = + alts (addLocals [bndr] env) (extendVarSet bounds bndr) as + go bounds (StgLet ext bind body) = + go_bind bounds (StgLet ext) bind body + go bounds (StgLetNoEscape ext bind body) = + go_bind bounds (StgLetNoEscape ext) bind body + go bounds (StgTick tick e) = + (StgTick tick e', fvs', da_fvs) + where + (e', fvs, da_fvs) = go bounds e + fvs' = unionDVarSet (tickish tick) fvs + tickish (Breakpoint _ ids) = mkDVarSet ids + tickish _ = emptyDVarSet + + go_bind bounds dc bind body = + ( dc bind' body' + , fvs + , da_bind_fvs `unionVarSet` da_body_fvs + ) + where + -- See Note [Tracking local binders] + binders = bindersOf bind + env' = addLocals binders env + (body', body_fvs, da_body_fvs) = + expr env' (extendVarSetList bounds binders) body + (bind', fvs, da_bind_fvs) = binding env' body_fvs bounds bind + + alts :: Env -> BVs -> [StgAlt] -> ([CgStgAlt], DIdSet, FVs) + alts env bounds as = + ( as' + , unionDVarSets alt_fvss + , unionVarSets alt_da_fvss + ) + where + (as', alt_fvss, alt_da_fvss) = mapAndUnzip3 (alt env bounds) as + + alt :: Env -> BVs -> StgAlt -> (CgStgAlt, DIdSet, FVs) + alt env bounds (con, bndrs, e) = + ( (con, bndrs, e') + , delDVarSetList rhs_fvs bndrs + , da_fvs + ) + where + (e', rhs_fvs, da_fvs) = expr (addLocals bndrs env) (extendVarSetList bounds bndrs) e + + args :: Env -> BVs -> [StgArg] -> (DIdSet, FVs) + args env bounds as = + ( mkFreeVarSet env (catMaybes mIds) + , unionVarSets da_fvss + ) + where + (mIds, da_fvss) = mapAndUnzip (arg bounds) as + + arg :: BVs -> StgArg -> (Maybe Id, FVs) + arg bounds (StgVarArg v) = (Just v, var bounds v) + arg _ StgLitArg{} = (Nothing, emptyVarSet) var :: BVs -> Var -> FVs var bounds v @@ -72,46 +196,6 @@ annTopBindingsDeps this_mod bs = map top_bind bs | otherwise = emptyVarSet - arg :: BVs -> StgArg -> FVs - arg bounds (StgVarArg v) = var bounds v - arg _ StgLitArg{} = emptyVarSet - - args :: BVs -> [StgArg] -> FVs - args bounds as = unionVarSets (map (arg bounds) as) - - expr :: BVs -> StgExpr -> FVs - expr bounds (StgApp f as) = - var bounds f `unionVarSet` args bounds as - - expr _ StgLit{} = - emptyVarSet - - expr bounds (StgConApp _ as _) = - args bounds as - expr bounds (StgOpApp _ as _) = - args bounds as - expr _ lam at StgLam{} = - pprPanic "annTopBindingsDeps" (text "Found lambda:" $$ ppr lam) - expr bounds (StgCase scrut scrut_bndr _ as) = - expr bounds scrut `unionVarSet` - alts (extendVarSet bounds scrut_bndr) as - expr bounds (StgLet _ bs e) = - binding bounds bs `unionVarSet` - expr (extendVarSetList bounds (bindersOf bs)) e - expr bounds (StgLetNoEscape _ bs e) = - binding bounds bs `unionVarSet` - expr (extendVarSetList bounds (bindersOf bs)) e - - expr bounds (StgTick _ e) = - expr bounds e - - alts :: BVs -> [StgAlt] -> FVs - alts bounds = unionVarSets . map (alt bounds) - - alt :: BVs -> StgAlt -> FVs - alt bounds (_, bndrs, e) = - expr (extendVarSetList bounds bndrs) e - -------------------------------------------------------------------------------- -- * Dependency sorting View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d489a92b5ff9bbf92d3f4a5177a8dcf5aeb2e99 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d489a92b5ff9bbf92d3f4a5177a8dcf5aeb2e99 You're receiving 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 4 03:05:58 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 03 Apr 2020 23:05:58 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sjakobi/foldl-unionManyUniqDSets Message-ID: <5e87f996640d9_616713279f6c2900081@gitlab.haskell.org.mail> Simon Jakobi pushed new branch wip/sjakobi/foldl-unionManyUniqDSets at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/foldl-unionManyUniqDSets You're receiving 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 4 03:07:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 03 Apr 2020 23:07:07 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e87f9db60cdf_61673f8198ee100c2902035@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - f61d4c39 by Ryan Scott at 2020-04-03T23:06:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Iface/Ext/Debug.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7470086a0c6617f020897ca1215a98561fabcf73...f61d4c39b4cadac0fd7fe1035fae8db4fa2c0542 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7470086a0c6617f020897ca1215a98561fabcf73...f61d4c39b4cadac0fd7fe1035fae8db4fa2c0542 You're receiving 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 4 11:07:28 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 04 Apr 2020 07:07:28 -0400 Subject: [Git][ghc/ghc][master] Revert accidental change in 9462452 Message-ID: <5e886a7052765_61673f81bb9e8b0429280c8@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - 1 changed file: - compiler/GHC/StgToCmm/DataCon.hs Changes: ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -1,6 +1,4 @@ {-# LANGUAGE CPP #-} -{-# OPTIONS -O -ddump-to-file -dumpdir datacondumps -ddump-simpl -ddump-stg #-} --- {-# OPTIONS -dsuppress-all #-} ----------------------------------------------------------------------------- -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/40a85563a46c682eaab5fdf970f7c46afca78cb3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/40a85563a46c682eaab5fdf970f7c46afca78cb3 You're receiving 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 4 11:08:09 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 04 Apr 2020 07:08:09 -0400 Subject: [Git][ghc/ghc][master] Enable ImpredicativeTypes internally when typechecking selector bindings Message-ID: <5e886a994cf4c_61673f81bb9e8b0429322c9@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 3 changed files: - compiler/typecheck/TcTyDecls.hs - + testsuite/tests/typecheck/should_compile/T18005.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/typecheck/TcTyDecls.hs ===================================== @@ -67,6 +67,7 @@ import Bag import FastString import FV import GHC.Types.Module +import qualified GHC.LanguageExtensions as LangExt import Control.Monad @@ -831,6 +832,8 @@ tcRecSelBinds :: [(Id, LHsBind GhcRn)] -> TcM TcGblEnv tcRecSelBinds sel_bind_prs = tcExtendGlobalValEnv [sel_id | (L _ (IdSig _ sel_id)) <- sigs] $ do { (rec_sel_binds, tcg_env) <- discardWarnings $ + -- See Note [Impredicative record selectors] + setXOptM LangExt.ImpredicativeTypes $ tcValBinds TopLevel binds sigs getGblEnv ; return (tcg_env `addTypecheckedBinds` map snd rec_sel_binds) } where @@ -1029,4 +1032,29 @@ The selector we want for fld looks like this: The scrutinee of the case has type :R7T (Maybe b), which can be gotten by applying the eq_spec to the univ_tvs of the data con. +Note [Impredicative record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There are situations where generating code for record selectors requires the +use of ImpredicativeTypes. Here is one example (adapted from #18005): + + type S = (forall b. b -> b) -> Int + data T = MkT {unT :: S} + | Dummy + +We want to generate HsBinds for unT that look something like this: + + unT :: S + unT (MkT x) = x + unT _ = recSelError "unT"# + +Note that the type of recSelError is `forall r (a :: TYPE r). Addr# -> a`. +Therefore, when used in the right-hand side of `unT`, GHC attempts to +instantiate `a` with `(forall b. b -> b) -> Int`, which is impredicative. +To make sure that GHC is OK with this, we enable ImpredicativeTypes interally +when typechecking these HsBinds so that the user does not have to. + +Although ImpredicativeTypes is somewhat fragile and unpredictable in GHC right +now, it will become robust when Quick Look impredicativity is implemented. In +the meantime, using ImpredicativeTypes to instantiate the `a` type variable in +recSelError's type does actually work, so its use here is benign. -} ===================================== testsuite/tests/typecheck/should_compile/T18005.hs ===================================== @@ -0,0 +1,30 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ViewPatterns #-} +module T18005 where + +type S1 = Int -> (forall a. a -> a) -> Int + +data T1a = MkT1a {unT1a :: S1} + | Dummy1 + +newtype T1b = MkT1b S1 + +unT1b' :: T1b -> S1 +unT1b' (MkT1b x) = x + +pattern MkT1b' :: S1 -> T1b +pattern MkT1b' {unT1b} <- (unT1b' -> unT1b) + +type S2 = Int -> forall a. a -> a + +data T2a = MkT2a {unT2a :: S2} + | Dummy2 + +newtype T2b = MkT2b S2 + +unT2b' :: T2b -> S2 +unT2b' (MkT2b x) = x + +pattern MkT2b' :: S2 -> T2b +pattern MkT2b' {unT2b} <- (unT2b' -> unT2b) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -701,3 +701,4 @@ test('T17710', normal, compile, ['']) test('T17792', normal, compile, ['']) test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) +test('T18005', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd75e5da0f1f05f107325733b570bf28b379d2f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd75e5da0f1f05f107325733b570bf28b379d2f2 You're receiving 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 4 14:46:34 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 04 Apr 2020 10:46:34 -0400 Subject: [Git][ghc/ghc][wip/T17775] 128 commits: pretty-printer: Properly parenthesise LastStmt Message-ID: <5e889dca78151_616776d1c74294803e@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 0333de05 by Simon Peyton Jones at 2020-04-04T09:57:10-04:00 Simplify subsumption This patch implements GHC Proposal 287: Simplify subsumption and ticket #17775. The highlights are: * No deeplyInstantiate or deeplySkolemise * No tcSubTypeDS Everything else is a knock-on effect. I did a bit of renaming to make things consistent * tcPolyExpr becomes tcCheckPolyExpr ditto tcPolyExprNC * Add new function tcCheckMonoExpr e ty = tcMon0Expr expr (mkCheckExpType ty) and use it This all comopiles, but needs some eta-expansion in haskeline, and doubtless other packages. - - - - - bb6f1d60 by Simon Peyton Jones at 2020-04-04T09:58:39-04:00 Further refactoring and simplification Reviewed the main changes with Richard I had to do eta-expansion in a number of tests: T10283 T10390 T14488 T1634 T4284 T9569a T9834 tc145 tc160 tc208 tc210 twins - - - - - 2d0b2564 by Ben Gamari at 2020-04-04T09:58:39-04:00 Bump haskeline submodule - - - - - 79e33feb by Simon Peyton Jones at 2020-04-04T09:58:39-04:00 Delete commented-out code - - - - - bff73ead by Simon Peyton Jones at 2020-04-04T09:58:39-04:00 Fix (breaking) typo - - - - - 049a44c8 by Simon Peyton Jones at 2020-04-04T10:00:54-04:00 Improve decomposition for FunTys This just improves error messages, avoiding Couldn't match type ‘Char’ with ‘Show a -> Char’ - - - - - bd8eda7c by Ryan Scott at 2020-04-04T10:00:54-04:00 Bump Cabal submodule As well as some miscellaneous fixes needed to make GHC itself compile under simplified subsumption. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/linters/check-cpp.py - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff50b0b54c29ab42b427ad2aa60087825f3baf6c...bd8eda7c22e8ccf88c2bf30de3edb69ba5519e2c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff50b0b54c29ab42b427ad2aa60087825f3baf6c...bd8eda7c22e8ccf88c2bf30de3edb69ba5519e2c You're receiving 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 4 16:17:45 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 04 Apr 2020 12:17:45 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e88b329ca04a_6167136dfb9c295175a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: 5d847cf0 by Ben Gamari at 2020-04-04T12:17:27-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 10 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/plugins/all.T - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1001,10 +1001,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1023,6 +1019,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1306,8 +1318,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1552,14 +1563,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1568,8 +1574,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3021,8 +3019,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,73 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/plugins/all.T ===================================== @@ -167,7 +167,6 @@ test('plugin-recomp-flags', test('plugin-recomp-change', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}') ], makefile_test, []) @@ -175,7 +174,6 @@ test('plugin-recomp-change', test('plugin-recomp-change-prof', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}'), when(not config.have_profiling,skip) ], ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d847cf0cda61a82643fde3ed98c5ba383341941 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d847cf0cda61a82643fde3ed98c5ba383341941 You're receiving 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 4 20:49:02 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Sat, 04 Apr 2020 16:49:02 -0400 Subject: [Git][ghc/ghc][wip/haddock-accum] 76 commits: Refactoring: use Platform instead of DynFlags when possible Message-ID: <5e88f2be12bd0_616713503ee029853ee@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/haddock-accum at Glasgow Haskell Compiler / GHC Commits: 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - a3ed45f3 by Vladislav Zavialov at 2020-04-04T23:48:49+03:00 Accumulate Haddock comments in P (#17544, #17561) Haddock comments are, first and foremost, comments. It's very annoying to incorporate them into the grammar. We can take advantage of an important property: adding a Haddock comment does not change the parse tree in any way other than wrapping some nodes in HsDocTy and the like (and if it does, that's a bug). This patch implements the following: * Accumulate Haddock comments with their locations in the P monad. This is handled in the lexer. * After parsing, do a pass over the AST to associate Haddock comments with AST nodes using location info. * Report the leftover comments to the user as a warning (-Winvalid-haddock). Metric Increase: T13719 ManyConstructors haddock.Cabal haddock.base haddock.compiler - - - - - 12eab816 by Vladislav Zavialov at 2020-04-04T23:48:49+03:00 Address review comments - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/linters/check-cpp.py - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2029a8999fb6c76656b25495e0bb9bb15bd00cea...12eab816437568698ce6772e2470f64c1daea32b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2029a8999fb6c76656b25495e0bb9bb15bd00cea...12eab816437568698ce6772e2470f64c1daea32b You're receiving 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 4 22:05:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 04 Apr 2020 18:05:23 -0400 Subject: [Git][ghc/ghc][wip/T15304] 12 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e8904a3bfc49_6167136dfb9c29953f1@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 37bc7a6c by Ben Gamari at 2020-04-04T18:05:15-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Iface/Ext/Debug.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d847cf0cda61a82643fde3ed98c5ba383341941...37bc7a6cbbfe885fe7c0f22dde6892c0f9a6ed11 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d847cf0cda61a82643fde3ed98c5ba383341941...37bc7a6cbbfe885fe7c0f22dde6892c0f9a6ed11 You're receiving 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 4 23:57:59 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Sat, 04 Apr 2020 19:57:59 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/foldl-unionManyUniqDSets] Use foldl' in unionManyUniqDSets Message-ID: <5e891f07beb85_61673f81bb9e8b04300917e@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/foldl-unionManyUniqDSets at Glasgow Haskell Compiler / GHC Commits: 32b6005d by Simon Jakobi at 2020-04-05T01:56:55+02:00 Use foldl' in unionManyUniqDSets - - - - - 1 changed file: - compiler/GHC/Types/Unique/DSet.hs Changes: ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -81,8 +81,8 @@ unionUniqDSets :: UniqDSet a -> UniqDSet a -> UniqDSet a unionUniqDSets (UniqDSet s) (UniqDSet t) = UniqDSet (plusUDFM s t) unionManyUniqDSets :: [UniqDSet a] -> UniqDSet a -unionManyUniqDSets [] = emptyUniqDSet -unionManyUniqDSets sets = foldr1 unionUniqDSets sets +unionManyUniqDSets [] = emptyUniqDSet +unionManyUniqDSets (x:xs) = foldl' unionUniqDSets x xs minusUniqDSet :: UniqDSet a -> UniqDSet a -> UniqDSet a minusUniqDSet (UniqDSet s) (UniqDSet t) = UniqDSet (minusUDFM s t) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/32b6005dd052b02313d00e7824ca3ed2e70d8085 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/32b6005dd052b02313d00e7824ca3ed2e70d8085 You're receiving 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 5 08:10:09 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Sun, 05 Apr 2020 04:10:09 -0400 Subject: [Git][ghc/ghc][wip/haddock-accum] Address review comments Message-ID: <5e899261973f9_61673f8198ee100c3015783@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/haddock-accum at Glasgow Haskell Compiler / GHC Commits: 13684b08 by Vladislav Zavialov at 2020-04-05T11:09:58+03:00 Address review comments - - - - - 5 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Types/SrcLoc.hs - compiler/main/HscStats.hs - compiler/parser/HaddockUtils.hs - compiler/utils/Util.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -91,7 +91,7 @@ module GHC.Hs.Decls ( HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, hsGroupInstDecls, hsGroupTopLevelFixitySigs, - partitionBindsAndSigs, flattenBindsAndSigs, + partitionBindsAndSigs, ) where -- friends: @@ -219,6 +219,8 @@ fields, this will result in an error (#17608). -- | Partition a list of HsDecl into function/pattern bindings, signatures, -- type family declarations, type family instances, and documentation comments. +-- +-- NB. Only works on HsDecls that can appear in a class declaration. partitionBindsAndSigs :: ((LHsBind GhcPs, [LHsDecl GhcPs]) -> (LHsBind GhcPs, [LHsDecl GhcPs])) -> [LHsDecl GhcPs] @@ -246,37 +248,6 @@ partitionBindsAndSigs getMonoBind = go -> (bs, ss, ts, tfis, dfis, L l d : docs) _ -> pprPanic "partitionBindsAndSigs" (ppr decl) --- | The inverse of 'partitionBindsAndSigs' that merges partitioned items --- back into a flat list. Elements are put back into the order in which they --- appeared in the original program before partitioning. -flattenBindsAndSigs - :: (LHsBinds GhcPs, [LSig GhcPs], [LFamilyDecl GhcPs], - [LTyFamInstDecl GhcPs], [LDataFamInstDecl GhcPs], [LDocDecl]) - -> [LHsDecl GhcPs] -flattenBindsAndSigs (all_bs, all_ss, all_ts, all_tfis, all_dfis, all_docs) = - sortLocatedUsingBufPos $ go (bagToList all_bs) all_ss all_ts all_tfis all_dfis all_docs - where - go (L l b : bs) ss ts tfis dfis docs = - L l (ValD noExtField b) - : go bs ss ts tfis dfis docs - go bs (L l s : ss) ts tfis dfis docs = - L l (SigD noExtField s) - : go bs ss ts tfis dfis docs - go bs ss (L l t : ts) tfis dfis docs = - L l (TyClD noExtField (FamDecl noExtField t)) - : go bs ss ts tfis dfis docs - go bs ss ts (L l tfi : tfis) dfis docs = - L l (InstD noExtField (TyFamInstD noExtField tfi)) - : go bs ss ts tfis dfis docs - go bs ss ts tfis (L l dfi : dfis) docs = - L l (InstD noExtField (DataFamInstD noExtField dfi)) - : go bs ss ts tfis dfis docs - go bs ss ts tfis dfis (L l d : docs) = - L l (DocD noExtField d) - : go bs ss ts tfis dfis docs - - go [] [] [] [] [] [] = [] - -- | Haskell Group -- -- A 'HsDecl' is categorised into a 'HsGroup' before being @@ -706,10 +677,29 @@ type instance XDataDecl GhcPs = NoExtField type instance XDataDecl GhcRn = DataDeclRn type instance XDataDecl GhcTc = DataDeclRn -type instance XClassDecl GhcPs = LayoutInfo +type instance XClassDecl GhcPs = LayoutInfo -- See Note [Class LayoutInfo] type instance XClassDecl GhcRn = NameSet -- FVs type instance XClassDecl GhcTc = NameSet -- FVs +{- Note [Class LayoutInfo] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +The LayoutInfo is used to associate Haddock comments with parts of the declaration. +Compare the following examples: + + class C a where + f :: a -> Int + -- ^ comment on f + + class C a where + f :: a -> Int + -- ^ comment on C + +Notice how "comment on f" and "comment on C" differ only by indentation level. +Thus we have to record the indentation level of the class declarations. + +See also Note [Adding Haddock comments to the syntax tree] in HaddockUtils. +-} + type instance XXTyClDecl (GhcPass _) = NoExtCon -- Simple classifiers for TyClDecl ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -90,8 +90,8 @@ module GHC.Types.SrcLoc ( -- ** Combining and comparing Located values eqLocated, cmpLocated, combineLocs, addCLoc, leftmost_smallest, leftmost_largest, rightmost_smallest, - spans, isSubspanOf, isRealSubspanOf, sortLocated, - sortLocatedUsingBufPos, sortRealLocated, + spans, isSubspanOf, isRealSubspanOf, + sortLocated, sortRealLocated, lookupSrcLoc, lookupSrcSpan, liftL, @@ -199,7 +199,7 @@ data RealSrcLoc -- -- Is the Haddock comment located between the module name and the data -- declaration? This is impossible to tell because the locations are not --- comparable, they even refer to different files. +-- comparable; they even refer to different files. -- -- On the other hand, with 'BufPos', we have the following location information: -- * The module name is located at 846-870 @@ -291,12 +291,6 @@ advanceBufPos (BufPos i) = BufPos (i+1) sortLocated :: [Located a] -> [Located a] sortLocated = sortBy (leftmost_smallest `on` getLoc) -sortLocatedUsingBufPos :: [Located a] -> [Located a] -sortLocatedUsingBufPos = sortBy (cmp `on` getLoc) - where - cmp (getBufSpan -> Just a) (getBufSpan -> Just b) = compare a b - cmp a b = leftmost_smallest a b - sortRealLocated :: [RealLocated a] -> [RealLocated a] sortRealLocated = sortBy (compare `on` getLoc) @@ -845,7 +839,7 @@ data LayoutInfo = -- bar :: a -- @ VirtualBraces - !Int -- ^ Layout column (indentation level) + !Int -- ^ Layout column (indentation level, begins at 1) | -- | Empty or compiler-generated blocks do not have layout information -- associated with them. ===================================== compiler/main/HscStats.hs ===================================== @@ -22,7 +22,7 @@ import Data.Char -- | Source Statistics ppSourceStats :: Bool -> Located HsModule -> SDoc -ppSourceStats short (L _ (HsModule _ _ exports imports ldecls _ _)) +ppSourceStats short (L _ (HsModule{ hsmodExports = exports, hsmodImports = imports, hsmodDecls = ldecls })) = (if short then hcat else vcat) (map pp_val [("ExportAll ", export_all), -- 1 if no export list ===================================== compiler/parser/HaddockUtils.hs ===================================== @@ -5,6 +5,8 @@ {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ViewPatterns #-} {- | This module implements 'addHaddockToModule', which inserts Haddock comments accumulated during parsing into the AST (#17544). @@ -52,6 +54,7 @@ import GHC.Hs import GHC.Types.SrcLoc import GHC.Driver.Session ( WarningFlag(..) ) import Outputable hiding ( (<>) ) +import Bag import Data.Semigroup import Data.Foldable @@ -63,6 +66,7 @@ import Data.Functor.Identity import Data.Coerce import Lexer +import Util (mergeListsBy) {- Note [Adding Haddock comments to the syntax tree] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -106,7 +110,7 @@ Ignoring the "->" allows us to accomodate alternative coding styles: Bool -- ^ comment on result Sometimes we also need to take indentation information into account. -Compare the following example: +Compare the following examples: class C a where f :: a -> Int @@ -781,3 +785,31 @@ that GHC could parse succesfully: This declaration was accepted by ghc but rejected by ghc -haddock. -} + +-- | The inverse of 'partitionBindsAndSigs' that merges partitioned items back +-- into a flat list. Elements are put back into the order in which they +-- appeared in the original program before partitioning, using BufPos to order +-- them. +-- +-- Precondition (unchecked): the input lists are already sorted. +flattenBindsAndSigs + :: (LHsBinds GhcPs, [LSig GhcPs], [LFamilyDecl GhcPs], + [LTyFamInstDecl GhcPs], [LDataFamInstDecl GhcPs], [LDocDecl]) + -> [LHsDecl GhcPs] +flattenBindsAndSigs (all_bs, all_ss, all_ts, all_tfis, all_dfis, all_docs) = + mergeListsBy cmp [ + map_l (\b -> ValD noExtField b) (bagToList all_bs), + map_l (\s -> SigD noExtField s) all_ss, + map_l (\t -> TyClD noExtField (FamDecl noExtField t)) all_ts, + map_l (\tfi -> InstD noExtField (TyFamInstD noExtField tfi)) all_tfis, + map_l (\dfi -> InstD noExtField (DataFamInstD noExtField dfi)) all_dfis, + map_l (\d -> DocD noExtField d) all_docs + ] + where + cmp :: LHsDecl GhcPs -> LHsDecl GhcPs -> Ordering + cmp (L (getBufSpan -> Just a) _) (L (getBufSpan -> Just b) _) = + compare a b + cmp _ _ = panic "flattenBindsAndSigs: HsDecl without BufSpan" + + map_l :: (a -> b) -> [Located a] -> [Located b] + map_l f = map (mapLoc f) ===================================== compiler/utils/Util.hs ===================================== @@ -5,6 +5,7 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE TupleSections #-} +{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -52,6 +53,8 @@ module Util ( whenNonEmpty, + mergeListsBy, + -- * Tuples fstOf3, sndOf3, thdOf3, firstM, first3M, secondM, @@ -611,6 +614,40 @@ whenNonEmpty :: Applicative m => [a] -> (NonEmpty a -> m ()) -> m () whenNonEmpty [] _ = pure () whenNonEmpty (x:xs) f = f (x :| xs) +-- | Merge an unsorted list of sorted lists, for example: +-- +-- mergeListsBy compare [ [2,5,15], [1,10,100] ] = [1,2,5,10,15,100] ] +mergeListsBy :: forall a. (a -> a -> Ordering) -> [[a]] -> [a] +mergeListsBy cmp lists | debugIsOn, not (all sorted lists) = + -- When debugging is on, we check that the input lists are sorted. + panic "mergeListsBy: input lists must be sorted" + where + sorted [] = True + sorted [_] = True + sorted (x:y:xs) = cmp x y /= GT && sorted (y:xs) +mergeListsBy cmp all_lists = merge_lists all_lists + where + merge2 :: [a] -> [a] -> [a] + merge2 [] ys = ys + merge2 xs [] = xs + merge2 (x:xs) (y:ys) = + case cmp x y of + GT -> y : merge2 (x:xs) ys + _ -> x : merge2 xs (y:ys) + + merge_neighbours :: [[a]] -> [[a]] + merge_neighbours [] = [] + merge_neighbours [xs] = [xs] + merge_neighbours (xs : ys : lists) = + merge2 xs ys : merge_neighbours lists + + merge_lists :: [[a]] -> [a] + merge_lists lists = + case merge_neighbours lists of + [] -> [] + [xs] -> xs + lists' -> merge_lists lists' + {- ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13684b084f41a24e31611e2afd33794e91e02cb8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13684b084f41a24e31611e2afd33794e91e02cb8 You're receiving 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 5 09:03:25 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Sun, 05 Apr 2020 05:03:25 -0400 Subject: [Git][ghc/ghc][wip/T17923] 25 commits: Clean up "Eta reduction for data families" Notes Message-ID: <5e899edd42cbc_6167134ebbc4301940@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/T17923 at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 92904edf by Simon Peyton Jones at 2020-04-05T05:03:22-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 28 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/677b7eaa88117290ccedd85e7a2e1079d378ba53...92904edf42b8bf154e3e6ab0680bb17d31d0d71b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/677b7eaa88117290ccedd85e7a2e1079d378ba53...92904edf42b8bf154e3e6ab0680bb17d31d0d71b You're receiving 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 5 11:35:42 2020 From: gitlab at gitlab.haskell.org (Peter Trommler) Date: Sun, 05 Apr 2020 07:35:42 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T11261 Message-ID: <5e89c28e5dccc_61673f8198ee100c30309ac@gitlab.haskell.org.mail> Peter Trommler pushed new branch wip/T11261 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T11261 You're receiving 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 5 12:40:25 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Sun, 05 Apr 2020 08:40:25 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 12 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e89d1b96f37_61673f8199536d943044555@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - f0fd786c by Ömer Sinan Ağacan at 2020-04-05T15:40:10+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ea89aee6c64c6351efc1ae4dbffe3193a29f3d9...f0fd786cb5bb8e4e4801e4a570ca23546ebc6ca7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ea89aee6c64c6351efc1ae4dbffe3193a29f3d9...f0fd786cb5bb8e4e4801e4a570ca23546ebc6ca7 You're receiving 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 5 16:11:13 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 05 Apr 2020 12:11:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18020 Message-ID: <5e8a0321a1fee_616776d1c74308526@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18020 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18020 You're receiving 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 5 21:40:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 05 Apr 2020 17:40:46 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e8a505e3fe50_61673f81ef22dee43113681@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: ec4e5640 by Ben Gamari at 2020-04-05T21:40:10+00:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 11 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/plugins/all.T - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1002,10 +1002,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1024,6 +1020,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1307,8 +1319,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1553,14 +1564,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1569,8 +1575,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3023,8 +3021,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,80 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/plugins/all.T ===================================== @@ -167,7 +167,6 @@ test('plugin-recomp-flags', test('plugin-recomp-change', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}') ], makefile_test, []) @@ -175,7 +174,6 @@ test('plugin-recomp-change', test('plugin-recomp-change-prof', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}'), when(not config.have_profiling,skip) ], ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -1,4 +1,5 @@ RULES: "SPEC $cm @()" [0] RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] +"SPEC/T17966 $fShowMaybe_$cshow @Integer" "SPEC/T17966 $fShowMaybe_$cshowList @Integer" "SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec4e5640e3d5edfba341ffb5d8c40a11603f818e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec4e5640e3d5edfba341ffb5d8c40a11603f818e You're receiving 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 6 03:22:24 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 05 Apr 2020 23:22:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/rename-test-envs Message-ID: <5e8aa0708cd00_6167136dfb9c31192eb@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/rename-test-envs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/rename-test-envs You're receiving 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 6 07:00:34 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 06 Apr 2020 03:00:34 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] 32 commits: Require GHC 8.8 as the minimum compiler for bootstrapping Message-ID: <5e8ad392562dc_61673f81bb9e8b043124043@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 27bd807b by Ömer Sinan Ağacan at 2020-04-06T09:25:16+03: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 hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - 3c85c406 by Ömer Sinan Ağacan at 2020-04-06T10:00:17+03:00 Fix std unpackCString# info tbl symbol, comment-out special case for non-top-lvl - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2899512ac1489ae8208dbe44e01762bb852f3e49...3c85c406977f018fba790b7fb7c1e14c1d6e0608 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2899512ac1489ae8208dbe44e01762bb852f3e49...3c85c406977f018fba790b7fb7c1e14c1d6e0608 You're receiving 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 6 07:14:39 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 06 Apr 2020 03:14:39 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Remove unused stuff Message-ID: <5e8ad6dfeee0c_61673f8199536d9431287b1@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 0fdc1369 by Ömer Sinan Ağacan at 2020-04-06T10:14:31+03:00 Remove unused stuff - - - - - 1 changed file: - compiler/GHC/StgToCmm/Closure.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -24,7 +24,6 @@ module GHC.StgToCmm.Closure ( LambdaFormInfo, -- Abstract StandardFormInfo, -- ...ditto... mkLFThunk, mkLFReEntrant, mkConLFInfo, mkSelectorLFInfo, - mkMkStringLFInfo, mkApLFInfo, mkLFImported, mkLFArgument, mkLFLetNoEscape, mkLFStringLit, lfDynTag, @@ -88,7 +87,6 @@ import GHC.Types.Basic import Outputable import GHC.Driver.Session import Util -import GHC.Stack (HasCallStack, prettyCallStack, callStack) import Data.Coerce (coerce) import qualified Data.ByteString.Char8 as BS8 @@ -260,8 +258,6 @@ data StandardFormInfo -- in the RTS to save space. RepArity -- Arity, n - | MkStringThunk - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -322,10 +318,6 @@ mkSelectorLFInfo id offset updatable = LFThunk NotTopLevel False updatable (SelectorThunk offset) (might_be_a_function (idType id)) -------------- -mkMkStringLFInfo :: Id -> LambdaFormInfo -mkMkStringLFInfo id = LFThunk TopLevel True True MkStringThunk False - ------------- mkApLFInfo :: Id -> UpdateFlag -> Arity -> LambdaFormInfo mkApLFInfo id upd_flag arity @@ -675,9 +667,7 @@ data ClosureInfo -- | Convert from 'ClosureInfo' to 'CmmInfoTable'. mkCmmInfo :: HasCallStack => ClosureInfo -> Id -> CostCentreStack -> CmmInfoTable mkCmmInfo ClosureInfo {..} id ccs - = pprTrace "mkCmmInfo" (text "info table label:" <+> ppr closureInfoLabel $$ - text (prettyCallStack callStack)) $ - CmmInfoTable { cit_lbl = closureInfoLabel + = CmmInfoTable { cit_lbl = closureInfoLabel , cit_rep = closureSMRep , cit_prof = closureProf , cit_srt = Nothing @@ -871,9 +861,6 @@ mkClosureInfoTableLabel id lf_info LFThunk _ _ upd_flag (ApThunk arity) _ -> mkApInfoTableLabel upd_flag arity - LFThunk TopLevel _ _ MkStringThunk _ - -> mkMkStringInfoTableLabel - LFThunk{} -> std_mk_lbl name cafs LFReEntrant{} -> std_mk_lbl name cafs _other -> panic "closureInfoTableLabel" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fdc136977e14043f8efaf9d9dd5c205cc282107 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fdc136977e14043f8efaf9d9dd5c205cc282107 You're receiving 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 6 08:51:38 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 06 Apr 2020 04:51:38 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Fix stg_MK_STRING_info closure type Message-ID: <5e8aed9aa1b14_616713503ee031368cf@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: e01dab1a by Ömer Sinan Ağacan at 2020-04-06T11:51:30+03:00 Fix stg_MK_STRING_info closure type - - - - - 1 changed file: - rts/StgStdThunks.cmm Changes: ===================================== rts/StgStdThunks.cmm ===================================== @@ -291,7 +291,7 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") Making strings -------------------------------------------------------------------------- */ -INFO_TABLE(stg_MK_STRING, 0, 0, FUN_STATIC, "stg_MK_STRING", "stg_MK_STRING") +INFO_TABLE(stg_MK_STRING, 0, 0, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") (P_ node) { W_ newCAF_ret; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e01dab1a88472335bc13d3ec95dc51feb2485606 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e01dab1a88472335bc13d3ec95dc51feb2485606 You're receiving 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 6 08:52:54 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 06 Apr 2020 04:52:54 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Fix stg_MK_STRING_info nptrs Message-ID: <5e8aede627134_616776d1c7431374e3@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: fefd226c by Ömer Sinan Ağacan at 2020-04-06T11:52:46+03:00 Fix stg_MK_STRING_info nptrs - - - - - 1 changed file: - rts/StgStdThunks.cmm Changes: ===================================== rts/StgStdThunks.cmm ===================================== @@ -291,7 +291,7 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") Making strings -------------------------------------------------------------------------- */ -INFO_TABLE(stg_MK_STRING, 0, 0, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") +INFO_TABLE(stg_MK_STRING, 0, 1, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") (P_ node) { W_ newCAF_ret; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fefd226c19e930a0db4fec9d1b865237e634b789 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fefd226c19e930a0db4fec9d1b865237e634b789 You're receiving 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 6 09:10:52 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 06 Apr 2020 05:10:52 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/reexport-noinline Message-ID: <5e8af21c956fa_616713503ee031399a@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/reexport-noinline at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/reexport-noinline You're receiving 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 6 10:26:03 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 06 Apr 2020 06:26:03 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Enable ImpredicativeTypes internally when typechecking selector bindings Message-ID: <5e8b03bb595c1_616776d1c74316203@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - 95ec9773 by Ömer Sinan Ağacan at 2020-04-06T06:25:53-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - 528d48c3 by Simon Peyton Jones at 2020-04-06T06:25:54-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - 76a1ea03 by Simon Peyton Jones at 2020-04-06T06:25:54-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - 10 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/typecheck/TcTyDecls.hs - + testsuite/tests/simplCore/should_run/T17151.hs - + testsuite/tests/simplCore/should_run/T17151.stdout - + testsuite/tests/simplCore/should_run/T17151a.hs - testsuite/tests/simplCore/should_run/all.T - + testsuite/tests/typecheck/should_compile/T18005.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -108,7 +108,7 @@ module GHC.Cmm.CLabel ( pprCLabel, isInfoTableLabel, isConInfoTableLabel, - isIdLabel + isIdLabel, isTickyLabel ) where #include "HsVersions.h" @@ -268,6 +268,12 @@ isIdLabel :: CLabel -> Bool isIdLabel IdLabel{} = True isIdLabel _ = False +-- Used in SRT analysis. See Note [Ticky labels in SRT analysis] in +-- GHC.Cmm.Info.Build. +isTickyLabel :: CLabel -> Bool +isTickyLabel (IdLabel _ _ RednCounts) = True +isTickyLabel _ = False + -- This is laborious, but necessary. We can't derive Ord because -- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the -- implementation. See Note [No Ord for Unique] @@ -462,8 +468,7 @@ mkSRTLabel :: Unique -> CLabel mkSRTLabel u = SRTLabel u mkRednCountsLabel :: Name -> CLabel -mkRednCountsLabel name = - IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] +mkRednCountsLabel name = IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] -- These have local & (possibly) external variants: mkLocalClosureLabel :: Name -> CafInfo -> CLabel ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -409,6 +409,30 @@ Maybe, but could you prove that RET_FUN is the only way that resurrection can occur? So, no shortcutting. + +Note [Ticky labels in SRT analysis] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Raw Cmm data (CmmStaticsRaw) can't contain pointers so they're considered +non-CAFFY in SRT analysis and we update the SRTMap mapping them to `Nothing` +(meaning they're not CAFFY). + +However when building with -ticky we generate ticky CLabels using the function's +`Name`. For example, if we have a top-level function `sat_s1rQ`, in a ticky +build we get two IdLabels using the name `sat_s1rQ`: + +- For the function itself: IdLabel sat_s1rQ ... Entry +- For the ticky counter: IdLabel sat_s1rQ ... RednCounts + +In these cases we really want to use the function definition for the SRT +analysis of this Name, because that's what we export for this Name -- ticky +counters are not exported. So we ignore ticky counters in SRT analysis (which +are never CAFFY and never exported). + +Not doing this caused #17947 where we analysed the function first mapped the +name to CAFFY. We then saw the ticky constructor, and becuase it has the same +Name as the function and is not CAFFY we overrode the CafInfo of the name as +non-CAFFY. -} -- --------------------------------------------------------------------- @@ -818,8 +842,11 @@ doSRTs dflags moduleSRTInfo procs data_ = do -- already updated by oneSRT srtMap CmmData _ (CmmStaticsRaw lbl _) - | isIdLabel lbl -> - -- not analysed by oneSRT, declare it non-CAFFY here + | isIdLabel lbl && not (isTickyLabel lbl) -> + -- Raw data are not analysed by oneSRT and they can't + -- be CAFFY. + -- See Note [Ticky labels in SRT analysis] above for + -- why we exclude ticky labels here. Map.insert (mkCAFLabel lbl) Nothing srtMap | otherwise -> -- Not an IdLabel, ignore ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -589,19 +589,11 @@ specProgram guts@(ModGuts { mg_module = this_mod -- Specialise the bindings of this module ; (binds', uds) <- runSpecM dflags this_mod (go binds) - -- Specialise imported functions - ; hpt_rules <- getRuleBase - ; let rule_base = extendRuleBaseList hpt_rules local_rules - ; (new_rules, spec_binds) <- specImports dflags this_mod top_env emptyVarSet - [] rule_base uds - - ; let final_binds - | null spec_binds = binds' - | otherwise = Rec (flattenBinds spec_binds) : binds' - -- Note [Glom the bindings if imported functions are specialised] + ; (spec_rules, spec_binds) <- specImports dflags this_mod top_env + local_rules uds - ; return (guts { mg_binds = final_binds - , mg_rules = new_rules ++ local_rules }) } + ; return (guts { mg_binds = spec_binds ++ binds' + , mg_rules = spec_rules ++ local_rules }) } where -- We need to start with a Subst that knows all the things -- that are in scope, so that the substitution engine doesn't @@ -645,72 +637,93 @@ See #10491 * * ********************************************************************* -} --- | Specialise a set of calls to imported bindings -specImports :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these ones - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module and the home package - -- (but not external packages, which can change) - -> UsageDetails -- Calls for imported things, and floating bindings - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings - -- See Note [Wrapping bindings returned by specImports] -specImports dflags this_mod top_env done callers rule_base +specImports :: DynFlags -> Module -> SpecEnv + -> [CoreRule] + -> UsageDetails + -> CoreM ([CoreRule], [CoreBind]) +specImports dflags this_mod top_env local_rules (MkUD { ud_binds = dict_binds, ud_calls = calls }) - -- See Note [Disabling cross-module specialisation] | not $ gopt Opt_CrossModuleSpecialise dflags - = return ([], []) + -- See Note [Disabling cross-module specialisation] + = return ([], wrapDictBinds dict_binds []) | otherwise - = do { let import_calls = dVarEnvElts calls - ; (rules, spec_binds) <- go rule_base import_calls + = do { hpt_rules <- getRuleBase + ; let rule_base = extendRuleBaseList hpt_rules local_rules + + ; (spec_rules, spec_binds) <- spec_imports dflags this_mod top_env + [] rule_base + dict_binds calls -- Don't forget to wrap the specialized bindings with -- bindings for the needed dictionaries. -- See Note [Wrap bindings returned by specImports] - ; let spec_binds' = wrapDictBinds dict_binds spec_binds + -- and Note [Glom the bindings if imported functions are specialised] + ; let final_binds + | null spec_binds = wrapDictBinds dict_binds [] + | otherwise = [Rec $ flattenBinds $ + wrapDictBinds dict_binds spec_binds] + + ; return (spec_rules, final_binds) + } + +-- | Specialise a set of calls to imported bindings +spec_imports :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module and the home package + -- (but not external packages, which can change) + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallDetails -- Calls for imported things + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_imports dflags this_mod top_env + callers rule_base dict_binds calls + = do { let import_calls = dVarEnvElts calls + -- ; debugTraceMsg (text "specImports {" <+> + -- vcat [ text "calls:" <+> ppr import_calls + -- , text "dict_binds:" <+> ppr dict_binds ]) + ; (rules, spec_binds) <- go rule_base import_calls + -- ; debugTraceMsg (text "End specImports }" <+> ppr import_calls) - ; return (rules, spec_binds') } + ; return (rules, spec_binds) } where go :: RuleBase -> [CallInfoSet] -> CoreM ([CoreRule], [CoreBind]) go _ [] = return ([], []) - go rb (cis@(CIS fn _) : other_calls) - = do { let ok_calls = filterCalls cis dict_binds - -- Drop calls that (directly or indirectly) refer to fn - -- See Note [Avoiding loops] --- ; debugTraceMsg (text "specImport" <+> vcat [ ppr fn --- , text "calls" <+> ppr cis --- , text "ud_binds =" <+> ppr dict_binds --- , text "dump set =" <+> ppr dump_set --- , text "filtered calls =" <+> ppr ok_calls ]) - ; (rules1, spec_binds1) <- specImport dflags this_mod top_env - done callers rb fn ok_calls + go rb (cis : other_calls) + = do { -- debugTraceMsg (text "specImport {" <+> ppr cis) + ; (rules1, spec_binds1) <- spec_import dflags this_mod top_env + callers rb dict_binds cis + -- ; debugTraceMsg (text "specImport }" <+> ppr cis) ; (rules2, spec_binds2) <- go (extendRuleBaseList rb rules1) other_calls ; return (rules1 ++ rules2, spec_binds1 ++ spec_binds2) } -specImport :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module - -> Id -> [CallInfo] -- Imported function and calls for it - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings -specImport dflags this_mod top_env done callers rb fn calls_for_fn - | fn `elemVarSet` done +spec_import :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallInfoSet -- Imported function and calls for it + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_import dflags this_mod top_env callers + rb dict_binds cis@(CIS fn _) + | isIn "specImport" fn callers = return ([], []) -- No warning. This actually happens all the time -- when specialising a recursive function, because -- the RHS of the specialised function contains a recursive -- call to the original function - | null calls_for_fn -- We filtered out all the calls in deleteCallsMentioning - = return ([], []) + | null good_calls + = do { -- debugTraceMsg (text "specImport:no valid calls") + ; return ([], []) } | wantSpecImport dflags unfolding , Just rhs <- maybeUnfoldingTemplate unfolding @@ -723,32 +736,37 @@ specImport dflags this_mod top_env done callers rb fn calls_for_fn ; let full_rb = unionRuleBase rb (eps_rule_base eps) rules_for_fn = getRules (RuleEnv full_rb vis_orphs) fn - ; (rules1, spec_pairs, uds) - <- -- pprTrace "specImport1" (vcat [ppr fn, ppr calls_for_fn, ppr rhs]) $ - runSpecM dflags this_mod $ - specCalls (Just this_mod) top_env rules_for_fn calls_for_fn fn rhs + ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls }) + <- do { -- debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls, ppr rhs]) + ; runSpecM dflags this_mod $ + specCalls (Just this_mod) top_env rules_for_fn good_calls fn rhs } ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs] -- After the rules kick in we may get recursion, but -- we rely on a global GlomBinds to sort that out later -- See Note [Glom the bindings if imported functions are specialised] -- Now specialise any cascaded calls - ; (rules2, spec_binds2) <- -- pprTrace "specImport 2" (ppr fn $$ ppr rules1 $$ ppr spec_binds1) $ - specImports dflags this_mod top_env - (extendVarSet done fn) - (fn:callers) - (extendRuleBaseList rb rules1) - uds + -- ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) + ; (rules2, spec_binds2) <- spec_imports dflags this_mod top_env + (fn:callers) + (extendRuleBaseList rb rules1) + (dict_binds `unionBags` dict_binds1) + new_calls - ; let final_binds = spec_binds2 ++ spec_binds1 + ; let final_binds = wrapDictBinds dict_binds1 $ + spec_binds2 ++ spec_binds1 ; return (rules2 ++ rules1, final_binds) } - | otherwise = do { tryWarnMissingSpecs dflags callers fn calls_for_fn - ; return ([], [])} + | otherwise + = do { tryWarnMissingSpecs dflags callers fn good_calls + ; return ([], [])} where unfolding = realIdUnfolding fn -- We want to see the unfolding even for loop breakers + good_calls = filterCalls cis dict_binds + -- SUPER IMPORTANT! Drop calls that (directly or indirectly) refer to fn + -- See Note [Avoiding loops in specImports] -- | Returns whether or not to show a missed-spec warning. -- If -Wall-missed-specializations is on, show the warning. @@ -790,8 +808,114 @@ wantSpecImport dflags unf -- inside it that we want to specialise | otherwise -> False -- Stable, not INLINE, hence INLINABLE -{- Note [Warning about missed specialisations] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Avoiding loops in specImports] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We must take great care when specialising instance declarations +(functions like $fOrdList) lest we accidentally build a recursive +dictionary. See Note [Avoiding loops]. + +The basic strategy of Note [Avoiding loops] is to use filterCalls +to discard loopy specialisations. But to do that we must ensure +that the in-scope dict-binds (passed to filterCalls) contains +all the needed dictionary bindings. In particular, in the recursive +call to spec_imorpts in spec_import, we must include the dict-binds +from the parent. Lacking this caused #17151, a really nasty bug. + +Here is what happened. +* Class struture: + Source is a superclass of Mut + Index is a superclass of Source + +* We started with these dict binds + dSource = $fSourcePix @Int $fIndexInt + dIndex = sc_sel dSource + dMut = $fMutPix @Int dIndex + and these calls to specialise + $fMutPix @Int dIndex + $fSourcePix @Int $fIndexInt + +* We specialised the call ($fMutPix @Int dIndex) + ==> new call ($fSourcePix @Int dIndex) + (because Source is a superclass of Mut) + +* We specialised ($fSourcePix @Int dIndex) + ==> produces specialised dict $s$fSourcePix, + a record with dIndex as a field + plus RULE forall d. ($fSourcePix @Int d) = $s$fSourcePix + *** This is the bogus step *** + +* Now we decide not to specialise the call + $fSourcePix @Int $fIndexInt + because we alredy have a RULE that matches it + +* Finally the simplifer rewrites + dSource = $fSourcePix @Int $fIndexInt + ==> dSource = $s$fSourcePix + +Disaster. Now we have + +Rewrite dSource's RHS to $s$fSourcePix Disaster + dSource = $s$fSourcePix + dIndex = sc_sel dSource + $s$fSourcePix = MkSource dIndex ... + +Solution: filterCalls should have stopped the bogus step, +by seeing that dIndex transitively uses $fSourcePix. But +it can only do that if it sees all the dict_binds. Wow. + +-------------- +Here's another example (#13429). Suppose we have + class Monoid v => C v a where ... + +We start with a call + f @ [Integer] @ Integer $fC[]Integer + +Specialising call to 'f' gives dict bindings + $dMonoid_1 :: Monoid [Integer] + $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer + + $dC_1 :: C [Integer] (Node [Integer] Integer) + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + +...plus a recursive call to + f @ [Integer] @ (Node [Integer] Integer) $dC_1 + +Specialising that call gives + $dMonoid_2 :: Monoid [Integer] + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + + $dC_2 :: C [Integer] (Node [Integer] Integer) + $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 + +Now we have two calls to the imported function + M.$fCvNode :: Monoid v => C v a + M.$fCvNode @v @a m = C m some_fun + +But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) +for specialisation, else we get: + + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + $s$fCvNode = C $dMonoid_2 ... + RULE M.$fCvNode [Integer] _ _ = $s$fCvNode + +Now use the rule to rewrite the call in the RHS of $dC_1 +and we get a loop! + + +Note [specImport call stack] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising an imports function 'f', we may get new calls +of an imported fuction 'g', which we want to specialise in turn, +and similarly specialising 'g' might expose a new call to 'h'. + +We track the stack of enclosing functions. So when specialising 'h' we +haev a specImport call stack of [g,f]. We do this for two reasons: +* Note [Warning about missed specialisations] +* Note [Avoiding recursive specialisation] + +Note [Warning about missed specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose * In module Lib, you carefully mark a function 'foo' INLINABLE * Import Lib(foo) into another module M @@ -807,6 +931,16 @@ is what Opt_WarnAllMissedSpecs does. ToDo: warn about missed opportunities for local functions. +Note [Avoiding recursive specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we specialise 'f' we may find new overloaded calls to 'g', 'h' in +'f's RHS. So we want to specialise g,h. But we don't want to +specialise f any more! It's possible that f's RHS might have a +recursive yet-more-specialised call, so we'd diverge in that case. +And if the call is to the same type, one specialisation is enough. +Avoiding this recursive specialisation loop is one reason for the +'callers' stack passed to specImports and specImport. + Note [Specialise imported INLINABLE things] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ What imported functions do we specialise? The basic set is @@ -842,15 +976,6 @@ make sure that f_spec is recursive. Easiest thing is to make all the specialisations for imported bindings recursive. -Note [Avoiding recursive specialisation] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When we specialise 'f' we may find new overloaded calls to 'g', 'h' in -'f's RHS. So we want to specialise g,h. But we don't want to -specialise f any more! It's possible that f's RHS might have a -recursive yet-more-specialised call, so we'd diverge in that case. -And if the call is to the same type, one specialisation is enough. -Avoiding this recursive specialisation loop is the reason for the -'done' VarSet passed to specImports and specImport. ************************************************************************ * * @@ -992,7 +1117,8 @@ specCase env scrut' case_bndr [(con, args, rhs)] ; (rhs', rhs_uds) <- specExpr env_rhs' rhs ; let scrut_bind = mkDB (NonRec case_bndr_flt scrut') case_bndr_set = unitVarSet case_bndr_flt - sc_binds = [(NonRec sc_arg_flt sc_rhs, case_bndr_set) + sc_binds = [ DB { db_bind = NonRec sc_arg_flt sc_rhs + , db_fvs = case_bndr_set } | (sc_arg_flt, sc_rhs) <- sc_args_flt `zip` sc_rhss ] flt_binds = scrut_bind : sc_binds (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds @@ -1115,7 +1241,7 @@ specBind rhs_env (NonRec fn rhs) body_uds else -- No call in final_uds mentions bound variables, -- so we can just leave the binding here - return (map fst final_binds, free_uds) } + return (map db_bind final_binds, free_uds) } specBind rhs_env (Rec pairs) body_uds @@ -1142,7 +1268,7 @@ specBind rhs_env (Rec pairs) body_uds ; if float_all then return ([], final_uds `snocDictBind` final_bind) else - return ([fst final_bind], final_uds) } + return ([db_bind final_bind], final_uds) } --------------------------- @@ -1621,8 +1747,10 @@ In general, we need only make this Rec if Note [Avoiding loops] ~~~~~~~~~~~~~~~~~~~~~ When specialising /dictionary functions/ we must be very careful to -avoid building loops. Here is an example that bit us badly: #3591 +avoid building loops. Here is an example that bit us badly, on +several distinct occasions. +Here is one: #3591 class Eq a => C a instance Eq [a] => C [a] @@ -1637,13 +1765,11 @@ This translates to None of these definitions is recursive. What happened was that we generated a specialisation: - RULE forall d. dfun T d = dT :: C [T] dT = (MkD a d (meth d)) [T/a, d1/d] = MkD T d1 (meth d1) But now we use the RULE on the RHS of d2, to get - d2 = dT = MkD d1 (meth d1) d1 = $p1 d2 @@ -1660,46 +1786,6 @@ Solution: (directly or indirectly) on the dfun we are specialising. This is done by 'filterCalls' --------------- -Here's another example, this time for an imported dfun, so the call -to filterCalls is in specImports (#13429). Suppose we have - class Monoid v => C v a where ... - -We start with a call - f @ [Integer] @ Integer $fC[]Integer - -Specialising call to 'f' gives dict bindings - $dMonoid_1 :: Monoid [Integer] - $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer - - $dC_1 :: C [Integer] (Node [Integer] Integer) - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - -...plus a recursive call to - f @ [Integer] @ (Node [Integer] Integer) $dC_1 - -Specialising that call gives - $dMonoid_2 :: Monoid [Integer] - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - - $dC_2 :: C [Integer] (Node [Integer] Integer) - $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 - -Now we have two calls to the imported function - M.$fCvNode :: Monoid v => C v a - M.$fCvNode @v @a m = C m some_fun - -But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) -for specialisation, else we get: - - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - $s$fCvNode = C $dMonoid_2 ... - RULE M.$fCvNode [Integer] _ _ = $s$fCvNode - -Now use the rule to rewrite the call in the RHS of $dC_1 -and we get a loop! - -------------- Here's yet another example @@ -2227,7 +2313,7 @@ data UsageDetails -- | A 'DictBind' is a binding along with a cached set containing its free -- variables (both type variables and dictionaries) -type DictBind = (CoreBind, VarSet) +data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet } {- Note [Floated dictionary bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2256,6 +2342,11 @@ So the DictBinds in (ud_binds :: Bag DictBind) may contain non-dictionary bindings too. -} +instance Outputable DictBind where + ppr (DB { db_bind = bind, db_fvs = fvs }) + = text "DB" <+> braces (sep [ text "bind:" <+> ppr bind + , text "fvs: " <+> ppr fvs ]) + instance Outputable UsageDetails where ppr (MkUD { ud_binds = dbs, ud_calls = calls }) = text "MkUD" <+> braces (sep (punctuate comma @@ -2304,8 +2395,8 @@ ppr_call_key_ty (SpecDict _) = Nothing ppr_call_key_ty UnspecArg = Nothing instance Outputable CallInfo where - ppr (CI { ci_key = key, ci_fvs = fvs }) - = text "CI" <> braces (hsep [ fsep (mapMaybe ppr_call_key_ty key), ppr fvs ]) + ppr (CI { ci_key = key, ci_fvs = _fvs }) + = text "CI" <> braces (sep (map ppr key)) unionCalls :: CallDetails -> CallDetails -> CallDetails unionCalls c1 c2 = plusDVarEnv_C unionCallInfoSet c1 c2 @@ -2491,11 +2582,11 @@ plusUDs (MkUD {ud_binds = db1, ud_calls = calls1}) ----------------------------- _dictBindBndrs :: Bag DictBind -> [Id] -_dictBindBndrs dbs = foldr ((++) . bindersOf . fst) [] dbs +_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs -- | Construct a 'DictBind' from a 'CoreBind' mkDB :: CoreBind -> DictBind -mkDB bind = (bind, bind_fvs bind) +mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind } -- | Identify the free variables of a 'CoreBind' bind_fvs :: CoreBind -> VarSet @@ -2526,17 +2617,18 @@ pair_fvs (bndr, rhs) = exprSomeFreeVars interesting rhs -- | Flatten a set of "dumped" 'DictBind's, and some other binding -- pairs, into a single recursive binding. -recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind ->DictBind +recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind -> DictBind recWithDumpedDicts pairs dbs - = (Rec bindings, fvs) + = DB { db_bind = Rec bindings, db_fvs = fvs } where - (bindings, fvs) = foldr add - ([], emptyVarSet) - (dbs `snocBag` mkDB (Rec pairs)) - add (NonRec b r, fvs') (pairs, fvs) = - ((b,r) : pairs, fvs `unionVarSet` fvs') - add (Rec prs1, fvs') (pairs, fvs) = - (prs1 ++ pairs, fvs `unionVarSet` fvs') + (bindings, fvs) = foldr add ([], emptyVarSet) + (dbs `snocBag` mkDB (Rec pairs)) + add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc) + = case bind of + NonRec b r -> ((b,r) : prs_acc, fvs') + Rec prs1 -> (prs1 ++ prs_acc, fvs') + where + fvs' = fvs_acc `unionVarSet` fvs snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails -- Add ud_binds to the tail end of the bindings in uds @@ -2556,13 +2648,13 @@ wrapDictBinds :: Bag DictBind -> [CoreBind] -> [CoreBind] wrapDictBinds dbs binds = foldr add binds dbs where - add (bind,_) binds = bind : binds + add (DB { db_bind = bind }) binds = bind : binds wrapDictBindsE :: Bag DictBind -> CoreExpr -> CoreExpr wrapDictBindsE dbs expr = foldr add expr dbs where - add (bind,_) expr = Let bind expr + add (DB { db_bind = bind }) expr = Let bind expr ---------------------- dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, Bag DictBind) @@ -2624,9 +2716,10 @@ filterCalls (CIS fn call_bag) dbs -- (_,_,dump_set) = splitDictBinds dbs {fn} -- But this variant is shorter - go so_far (db,fvs) | fvs `intersectsVarSet` so_far - = extendVarSetList so_far (bindersOf db) - | otherwise = so_far + go so_far (DB { db_bind = bind, db_fvs = fvs }) + | fvs `intersectsVarSet` so_far + = extendVarSetList so_far (bindersOf bind) + | otherwise = so_far ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) @@ -2643,8 +2736,9 @@ splitDictBinds dbs bndr_set -- Important that it's foldl' not foldr; -- we're accumulating the set of dumped ids in dump_set where - split_db (free_dbs, dump_dbs, dump_idset) db@(bind, fvs) - | dump_idset `intersectsVarSet` fvs -- Dump it + split_db (free_dbs, dump_dbs, dump_idset) db + | DB { db_bind = bind, db_fvs = fvs } <- db + , dump_idset `intersectsVarSet` fvs -- Dump it = (free_dbs, dump_dbs `snocBag` db, extendVarSetList dump_idset (bindersOf bind)) ===================================== compiler/typecheck/TcTyDecls.hs ===================================== @@ -67,6 +67,7 @@ import Bag import FastString import FV import GHC.Types.Module +import qualified GHC.LanguageExtensions as LangExt import Control.Monad @@ -831,6 +832,8 @@ tcRecSelBinds :: [(Id, LHsBind GhcRn)] -> TcM TcGblEnv tcRecSelBinds sel_bind_prs = tcExtendGlobalValEnv [sel_id | (L _ (IdSig _ sel_id)) <- sigs] $ do { (rec_sel_binds, tcg_env) <- discardWarnings $ + -- See Note [Impredicative record selectors] + setXOptM LangExt.ImpredicativeTypes $ tcValBinds TopLevel binds sigs getGblEnv ; return (tcg_env `addTypecheckedBinds` map snd rec_sel_binds) } where @@ -1029,4 +1032,29 @@ The selector we want for fld looks like this: The scrutinee of the case has type :R7T (Maybe b), which can be gotten by applying the eq_spec to the univ_tvs of the data con. +Note [Impredicative record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There are situations where generating code for record selectors requires the +use of ImpredicativeTypes. Here is one example (adapted from #18005): + + type S = (forall b. b -> b) -> Int + data T = MkT {unT :: S} + | Dummy + +We want to generate HsBinds for unT that look something like this: + + unT :: S + unT (MkT x) = x + unT _ = recSelError "unT"# + +Note that the type of recSelError is `forall r (a :: TYPE r). Addr# -> a`. +Therefore, when used in the right-hand side of `unT`, GHC attempts to +instantiate `a` with `(forall b. b -> b) -> Int`, which is impredicative. +To make sure that GHC is OK with this, we enable ImpredicativeTypes interally +when typechecking these HsBinds so that the user does not have to. + +Although ImpredicativeTypes is somewhat fragile and unpredictable in GHC right +now, it will become robust when Quick Look impredicativity is implemented. In +the meantime, using ImpredicativeTypes to instantiate the `a` type variable in +recSelError's type does actually work, so its use here is benign. -} ===================================== testsuite/tests/simplCore/should_run/T17151.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE FlexibleContexts #-} +module Main where + +import T17151a + +main :: IO () +main = do + let ys :: Array P Int Int + ys = computeS (makeArray D 1 (const 5)) + applyStencil :: + (Source P ix Int, Load D ix Int) + => Stencil ix Int Int + -> Array P ix Int + -> Array P ix Int + applyStencil s = computeS . mapStencil s + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) ===================================== testsuite/tests/simplCore/should_run/T17151.stdout ===================================== @@ -0,0 +1,2 @@ +55 +55 ===================================== testsuite/tests/simplCore/should_run/T17151a.hs ===================================== @@ -0,0 +1,205 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE EmptyDataDecls #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +module T17151a + ( computeS + , Stencil + , P(..) + , D(..) + , makeConvolutionStencilFromKernel + , mapStencil + , Array + , Construct(..) + , Source(..) + , Load(..) + , Mutable(..) + ) where + +import Control.Monad.ST +import Data.Functor.Identity +import GHC.STRef +import GHC.ST +import GHC.Exts +import Unsafe.Coerce +import Data.Kind + +---- Hacked up stuff to simulate primitive package +class Prim e where + indexByteArray :: ByteArray -> Int -> e + sizeOf :: e ->Int +instance Prim Int where + indexByteArray _ _ = 55 + sizeOf _ = 99 + +data ByteArray = BA +type MutableByteArray s = STRef s Int + +class Monad m => PrimMonad m where + type PrimState m + primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a +instance PrimMonad (ST s) where + type PrimState (ST s) = s + primitive = ST + +unsafeFreezeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> m ByteArray +unsafeFreezeByteArray a = return (unsafeCoerce a) + +newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m)) +newByteArray (I# n#) + = primitive (\s# -> case newMutVar# 33 s# of + (# s'#, arr# #) -> (# s'#, STRef arr# #)) + +writeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> e -> m () +writeByteArray _ _ _ = return () + +----- End of hacked up stuff + +-------------- +newtype Stencil ix e a = + Stencil ((ix -> e) -> ix -> a) + +mapStencil :: Source r ix e => Stencil ix e a -> Array r ix e -> Array D ix a +mapStencil (Stencil stencilF) arr = DArray (size arr) (stencilF (unsafeIndex arr)) +{-# INLINE mapStencil #-} + +makeConvolutionStencilFromKernel + :: (Source r ix e, Num e) + => Array r ix e + -> Stencil ix e e +makeConvolutionStencilFromKernel arr = Stencil stencil + where + sz = size arr + sCenter = liftIndex (`quot` 2) sz + stencil getVal ix = + runIdentity $ + loopM 0 (< totalElem sz) (+ 1) 0 $ \i a -> + pure $ accum a (fromLinearIndex sz i) (unsafeLinearIndex arr i) + where + ixOff = liftIndex2 (+) ix sCenter + accum acc kIx kVal = getVal (liftIndex2 (-) ixOff kIx) * kVal + acc + {-# INLINE accum #-} + {-# INLINE stencil #-} +{-# INLINE makeConvolutionStencilFromKernel #-} + + +computeS :: (Mutable r ix e, Load r' ix e) => Array r' ix e -> Array r ix e +computeS arr = runST $ do + marr <- unsafeNew (size arr) + unsafeLoadIntoS marr arr + unsafeFreeze marr +{-# INLINE computeS #-} + + +data D = D deriving Show + +data instance Array D ix e = DArray{dSize :: ix, + dIndex :: ix -> e} + +instance Index ix => Construct D ix e where + makeArray _ = DArray + {-# INLINE makeArray #-} + +instance Index ix => Source D ix e where + unsafeIndex = dIndex + {-# INLINE unsafeIndex #-} + +instance Index ix => Load D ix e where + size = dSize + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +data P = P deriving Show + +data instance Array P ix e = PArray ix ByteArray + +instance (Prim e, Index ix) => Construct P ix e where + makeArray _ sz f = computeS (makeArray D sz f) + {-# INLINE makeArray #-} + +instance (Prim e, Index ix) => Source P ix e where + unsafeIndex (PArray sz a) = indexByteArray a . toLinearIndex sz + {-# INLINE unsafeIndex #-} + +instance (Prim e, Index ix) => Mutable P ix e where + data MArray s P ix e = MPArray ix (MutableByteArray s) + unsafeFreeze (MPArray sz a) = PArray sz <$> unsafeFreezeByteArray a + {-# INLINE unsafeFreeze #-} + unsafeNew sz = MPArray sz <$> newByteArray (totalElem sz * eSize) + where + eSize = sizeOf (undefined :: e) + {-# INLINE unsafeNew #-} + unsafeLinearWrite (MPArray _ ma) = writeByteArray ma + {-# INLINE unsafeLinearWrite #-} + + +instance (Prim e, Index ix) => Load P ix e where + size (PArray sz _) = sz + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +unsafeLinearIndex :: Source r ix e => Array r ix e -> Int -> e +unsafeLinearIndex arr = unsafeIndex arr . fromLinearIndex (size arr) +{-# INLINE unsafeLinearIndex #-} + + +loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a +loopM init' condition increment initAcc f = go init' initAcc + where + go step acc + | condition step = f step acc >>= go (increment step) + | otherwise = return acc +{-# INLINE loopM #-} + +splitLinearlyWith_ :: + Monad m => Int -> (Int -> b) -> (Int -> b -> m ()) -> m () +splitLinearlyWith_ totalLength index write = + loopM 0 (< totalLength) (+1) () $ \i () -> write i (index i) +{-# INLINE splitLinearlyWith_ #-} + + +data family Array r ix e :: Type + +class Index ix => Construct r ix e where + makeArray :: r -> ix -> (ix -> e) -> Array r ix e + +class Load r ix e => Source r ix e where + unsafeIndex :: Array r ix e -> ix -> e + +class Index ix => Load r ix e where + size :: Array r ix e -> ix + loadArrayM :: Monad m => Array r ix e -> (Int -> e -> m ()) -> m () + unsafeLoadIntoS :: + (Mutable r' ix e, PrimMonad m) => MArray (PrimState m) r' ix e -> Array r ix e -> m () + unsafeLoadIntoS marr arr = loadArrayM arr (unsafeLinearWrite marr) + {-# INLINE unsafeLoadIntoS #-} + +class (Construct r ix e, Source r ix e) => Mutable r ix e where + data MArray s r ix e :: Type + unsafeFreeze :: PrimMonad m => MArray (PrimState m) r ix e -> m (Array r ix e) + unsafeNew :: PrimMonad m => ix -> m (MArray (PrimState m) r ix e) + unsafeLinearWrite :: PrimMonad m => MArray (PrimState m) r ix e -> Int -> e -> m () + + +class (Eq ix, Ord ix, Show ix) => + Index ix + where + totalElem :: ix -> Int + liftIndex2 :: (Int -> Int -> Int) -> ix -> ix -> ix + liftIndex :: (Int -> Int) -> ix -> ix + toLinearIndex :: ix -> ix -> Int + fromLinearIndex :: ix -> Int -> ix + +instance Index Int where + totalElem = id + toLinearIndex _ = id + fromLinearIndex _ = id + liftIndex f = f + liftIndex2 f = f ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -92,3 +92,4 @@ test('T15840', normal, compile_and_run, ['']) test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) +test('T17151', [], multimod_compile_and_run, ['T17151', '']) ===================================== testsuite/tests/typecheck/should_compile/T18005.hs ===================================== @@ -0,0 +1,30 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ViewPatterns #-} +module T18005 where + +type S1 = Int -> (forall a. a -> a) -> Int + +data T1a = MkT1a {unT1a :: S1} + | Dummy1 + +newtype T1b = MkT1b S1 + +unT1b' :: T1b -> S1 +unT1b' (MkT1b x) = x + +pattern MkT1b' :: S1 -> T1b +pattern MkT1b' {unT1b} <- (unT1b' -> unT1b) + +type S2 = Int -> forall a. a -> a + +data T2a = MkT2a {unT2a :: S2} + | Dummy2 + +newtype T2b = MkT2b S2 + +unT2b' :: T2b -> S2 +unT2b' (MkT2b x) = x + +pattern MkT2b' :: S2 -> T2b +pattern MkT2b' {unT2b} <- (unT2b' -> unT2b) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -701,3 +701,4 @@ test('T17710', normal, compile, ['']) test('T17792', normal, compile, ['']) test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) +test('T18005', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f61d4c39b4cadac0fd7fe1035fae8db4fa2c0542...76a1ea0374d9c83032f599fdc93543d1ddbca8e5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f61d4c39b4cadac0fd7fe1035fae8db4fa2c0542...76a1ea0374d9c83032f599fdc93543d1ddbca8e5 You're receiving 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 6 11:36:47 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 06 Apr 2020 07:36:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/large_address_space Message-ID: <5e8b144f3a477_616713503ee031761c6@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/large_address_space at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/large_address_space You're receiving 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 6 13:42:02 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 06 Apr 2020 09:42:02 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e8b31aa92165_61673f8198ee100c31935cf@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: f32925d8 by Ben Gamari at 2020-04-05T23:22:04-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 9 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/plugins/all.T - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1002,10 +1002,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1024,6 +1020,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1307,8 +1319,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1553,14 +1564,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1569,8 +1575,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3023,8 +3021,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/plugins/all.T ===================================== @@ -167,7 +167,6 @@ test('plugin-recomp-flags', test('plugin-recomp-change', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}') ], makefile_test, []) @@ -175,7 +174,6 @@ test('plugin-recomp-change', test('plugin-recomp-change-prof', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}'), when(not config.have_profiling,skip) ], ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f32925d8fe7dfd3c704987a8c48fcc29c09a345a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f32925d8fe7dfd3c704987a8c48fcc29c09a345a You're receiving 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 6 15:46:35 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 06 Apr 2020 11:46:35 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Hopefully fix the perf regression Message-ID: <5e8b4edbbfc7e_61673f81bb9e8b04321908f@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 76015226 by Sebastian Graf at 2020-04-06T17:46:26+02:00 Hopefully fix the perf regression - - - - - 1 changed file: - compiler/GHC/Core/Op/DmdAnal.hs Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -152,7 +152,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +410,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -518,19 +518,35 @@ dmdTransform env var dmd = dmdTransformDictSelSig (idStrictness var) dmd | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:global" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:local" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl then fn_ty -- Don't record top level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + = mkConservativeSig env var (unitVarEnv var (mkOnceUsedDmd dmd)) + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig emptyVarEnv env (idType var) + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> VarEnv -> Type -> StrictSig +mkConservativeSig env ty fvs + = tryClearPreciseException fam_envs ty optimistic_sig + where + fam_envs = ae_fam_envs env + -- This is almost isomorphic to topSig, except for the Divergence! + optimistic_sig = StrictSig $ DmdType fvs optimistic_args conDiv + optimistic_args = replicate (length (typeArity ty)) topDmd {- ************************************************************************ @@ -944,9 +960,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7601522602e95c4a1a013f0d24b3d57e8a213aee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7601522602e95c4a1a013f0d24b3d57e8a213aee You're receiving 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 6 15:57:46 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 06 Apr 2020 11:57:46 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Hopefully fix the perf regression Message-ID: <5e8b517a118ca_616776d1c7432262b4@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 8ae14a25 by Sebastian Graf at 2020-04-06T17:57:37+02:00 Hopefully fix the perf regression - - - - - 1 changed file: - compiler/GHC/Core/Op/DmdAnal.hs Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -27,6 +27,7 @@ import Data.List ( mapAccumL ) import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Core.Arity ( typeArity ) import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type @@ -152,7 +153,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +411,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -518,19 +519,37 @@ dmdTransform env var dmd = dmdTransformDictSelSig (idStrictness var) dmd | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:global" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:local" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl then fn_ty -- Don't record top level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + = dmdTransformSig (mkConservativeSig env (idType var) (unitVarEnv var (mkOnceUsedDmd dmd))) dmd + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig env (idType var) emptyVarEnv + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> Type -> DmdEnv -> StrictSig +mkConservativeSig env ty fvs + = tryClearPreciseException fam_envs ty pessimistic_sig + where + fam_envs = ae_fam_envs env + -- This is isomorphic to topSig. But this one has the right number of + -- arguments and will possibly have conDiv after the call to + -- tryClearPreciseException! + pessimistic_sig = StrictSig $ DmdType fvs args conDiv + args = replicate (length (typeArity ty)) topDmd {- ************************************************************************ @@ -944,9 +963,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ae14a25c07748b23f79dd67cfd01b8f814ff9da -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ae14a25c07748b23f79dd67cfd01b8f814ff9da You're receiving 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 6 17:16:18 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 06 Apr 2020 13:16:18 -0400 Subject: [Git][ghc/ghc][master] Don't override proc CafInfos in ticky builds Message-ID: <5e8b63e2c091_616713279f6c3265274@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - 2 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -108,7 +108,7 @@ module GHC.Cmm.CLabel ( pprCLabel, isInfoTableLabel, isConInfoTableLabel, - isIdLabel + isIdLabel, isTickyLabel ) where #include "HsVersions.h" @@ -268,6 +268,12 @@ isIdLabel :: CLabel -> Bool isIdLabel IdLabel{} = True isIdLabel _ = False +-- Used in SRT analysis. See Note [Ticky labels in SRT analysis] in +-- GHC.Cmm.Info.Build. +isTickyLabel :: CLabel -> Bool +isTickyLabel (IdLabel _ _ RednCounts) = True +isTickyLabel _ = False + -- This is laborious, but necessary. We can't derive Ord because -- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the -- implementation. See Note [No Ord for Unique] @@ -462,8 +468,7 @@ mkSRTLabel :: Unique -> CLabel mkSRTLabel u = SRTLabel u mkRednCountsLabel :: Name -> CLabel -mkRednCountsLabel name = - IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] +mkRednCountsLabel name = IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] -- These have local & (possibly) external variants: mkLocalClosureLabel :: Name -> CafInfo -> CLabel ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -409,6 +409,30 @@ Maybe, but could you prove that RET_FUN is the only way that resurrection can occur? So, no shortcutting. + +Note [Ticky labels in SRT analysis] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Raw Cmm data (CmmStaticsRaw) can't contain pointers so they're considered +non-CAFFY in SRT analysis and we update the SRTMap mapping them to `Nothing` +(meaning they're not CAFFY). + +However when building with -ticky we generate ticky CLabels using the function's +`Name`. For example, if we have a top-level function `sat_s1rQ`, in a ticky +build we get two IdLabels using the name `sat_s1rQ`: + +- For the function itself: IdLabel sat_s1rQ ... Entry +- For the ticky counter: IdLabel sat_s1rQ ... RednCounts + +In these cases we really want to use the function definition for the SRT +analysis of this Name, because that's what we export for this Name -- ticky +counters are not exported. So we ignore ticky counters in SRT analysis (which +are never CAFFY and never exported). + +Not doing this caused #17947 where we analysed the function first mapped the +name to CAFFY. We then saw the ticky constructor, and becuase it has the same +Name as the function and is not CAFFY we overrode the CafInfo of the name as +non-CAFFY. -} -- --------------------------------------------------------------------- @@ -818,8 +842,11 @@ doSRTs dflags moduleSRTInfo procs data_ = do -- already updated by oneSRT srtMap CmmData _ (CmmStaticsRaw lbl _) - | isIdLabel lbl -> - -- not analysed by oneSRT, declare it non-CAFFY here + | isIdLabel lbl && not (isTickyLabel lbl) -> + -- Raw data are not analysed by oneSRT and they can't + -- be CAFFY. + -- See Note [Ticky labels in SRT analysis] above for + -- why we exclude ticky labels here. Map.insert (mkCAFLabel lbl) Nothing srtMap | otherwise -> -- Not an IdLabel, ignore View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcfe29c8520244764146c7a5f336be1f9700db6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcfe29c8520244764146c7a5f336be1f9700db6c You're receiving 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 6 17:16:55 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 06 Apr 2020 13:16:55 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Fix an tricky specialiser loop Message-ID: <5e8b6407486d8_61673f8198ee100c3268380@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - 5 changed files: - compiler/GHC/Core/Op/Specialise.hs - + testsuite/tests/simplCore/should_run/T17151.hs - + testsuite/tests/simplCore/should_run/T17151.stdout - + testsuite/tests/simplCore/should_run/T17151a.hs - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -589,19 +589,11 @@ specProgram guts@(ModGuts { mg_module = this_mod -- Specialise the bindings of this module ; (binds', uds) <- runSpecM dflags this_mod (go binds) - -- Specialise imported functions - ; hpt_rules <- getRuleBase - ; let rule_base = extendRuleBaseList hpt_rules local_rules - ; (new_rules, spec_binds) <- specImports dflags this_mod top_env emptyVarSet - [] rule_base uds - - ; let final_binds - | null spec_binds = binds' - | otherwise = Rec (flattenBinds spec_binds) : binds' - -- Note [Glom the bindings if imported functions are specialised] + ; (spec_rules, spec_binds) <- specImports dflags this_mod top_env + local_rules uds - ; return (guts { mg_binds = final_binds - , mg_rules = new_rules ++ local_rules }) } + ; return (guts { mg_binds = spec_binds ++ binds' + , mg_rules = spec_rules ++ local_rules }) } where -- We need to start with a Subst that knows all the things -- that are in scope, so that the substitution engine doesn't @@ -645,72 +637,93 @@ See #10491 * * ********************************************************************* -} --- | Specialise a set of calls to imported bindings -specImports :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these ones - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module and the home package - -- (but not external packages, which can change) - -> UsageDetails -- Calls for imported things, and floating bindings - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings - -- See Note [Wrapping bindings returned by specImports] -specImports dflags this_mod top_env done callers rule_base +specImports :: DynFlags -> Module -> SpecEnv + -> [CoreRule] + -> UsageDetails + -> CoreM ([CoreRule], [CoreBind]) +specImports dflags this_mod top_env local_rules (MkUD { ud_binds = dict_binds, ud_calls = calls }) - -- See Note [Disabling cross-module specialisation] | not $ gopt Opt_CrossModuleSpecialise dflags - = return ([], []) + -- See Note [Disabling cross-module specialisation] + = return ([], wrapDictBinds dict_binds []) | otherwise - = do { let import_calls = dVarEnvElts calls - ; (rules, spec_binds) <- go rule_base import_calls + = do { hpt_rules <- getRuleBase + ; let rule_base = extendRuleBaseList hpt_rules local_rules + + ; (spec_rules, spec_binds) <- spec_imports dflags this_mod top_env + [] rule_base + dict_binds calls -- Don't forget to wrap the specialized bindings with -- bindings for the needed dictionaries. -- See Note [Wrap bindings returned by specImports] - ; let spec_binds' = wrapDictBinds dict_binds spec_binds + -- and Note [Glom the bindings if imported functions are specialised] + ; let final_binds + | null spec_binds = wrapDictBinds dict_binds [] + | otherwise = [Rec $ flattenBinds $ + wrapDictBinds dict_binds spec_binds] + + ; return (spec_rules, final_binds) + } + +-- | Specialise a set of calls to imported bindings +spec_imports :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module and the home package + -- (but not external packages, which can change) + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallDetails -- Calls for imported things + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_imports dflags this_mod top_env + callers rule_base dict_binds calls + = do { let import_calls = dVarEnvElts calls + -- ; debugTraceMsg (text "specImports {" <+> + -- vcat [ text "calls:" <+> ppr import_calls + -- , text "dict_binds:" <+> ppr dict_binds ]) + ; (rules, spec_binds) <- go rule_base import_calls + -- ; debugTraceMsg (text "End specImports }" <+> ppr import_calls) - ; return (rules, spec_binds') } + ; return (rules, spec_binds) } where go :: RuleBase -> [CallInfoSet] -> CoreM ([CoreRule], [CoreBind]) go _ [] = return ([], []) - go rb (cis@(CIS fn _) : other_calls) - = do { let ok_calls = filterCalls cis dict_binds - -- Drop calls that (directly or indirectly) refer to fn - -- See Note [Avoiding loops] --- ; debugTraceMsg (text "specImport" <+> vcat [ ppr fn --- , text "calls" <+> ppr cis --- , text "ud_binds =" <+> ppr dict_binds --- , text "dump set =" <+> ppr dump_set --- , text "filtered calls =" <+> ppr ok_calls ]) - ; (rules1, spec_binds1) <- specImport dflags this_mod top_env - done callers rb fn ok_calls + go rb (cis : other_calls) + = do { -- debugTraceMsg (text "specImport {" <+> ppr cis) + ; (rules1, spec_binds1) <- spec_import dflags this_mod top_env + callers rb dict_binds cis + -- ; debugTraceMsg (text "specImport }" <+> ppr cis) ; (rules2, spec_binds2) <- go (extendRuleBaseList rb rules1) other_calls ; return (rules1 ++ rules2, spec_binds1 ++ spec_binds2) } -specImport :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module - -> Id -> [CallInfo] -- Imported function and calls for it - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings -specImport dflags this_mod top_env done callers rb fn calls_for_fn - | fn `elemVarSet` done +spec_import :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallInfoSet -- Imported function and calls for it + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_import dflags this_mod top_env callers + rb dict_binds cis@(CIS fn _) + | isIn "specImport" fn callers = return ([], []) -- No warning. This actually happens all the time -- when specialising a recursive function, because -- the RHS of the specialised function contains a recursive -- call to the original function - | null calls_for_fn -- We filtered out all the calls in deleteCallsMentioning - = return ([], []) + | null good_calls + = do { -- debugTraceMsg (text "specImport:no valid calls") + ; return ([], []) } | wantSpecImport dflags unfolding , Just rhs <- maybeUnfoldingTemplate unfolding @@ -723,32 +736,37 @@ specImport dflags this_mod top_env done callers rb fn calls_for_fn ; let full_rb = unionRuleBase rb (eps_rule_base eps) rules_for_fn = getRules (RuleEnv full_rb vis_orphs) fn - ; (rules1, spec_pairs, uds) - <- -- pprTrace "specImport1" (vcat [ppr fn, ppr calls_for_fn, ppr rhs]) $ - runSpecM dflags this_mod $ - specCalls (Just this_mod) top_env rules_for_fn calls_for_fn fn rhs + ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls }) + <- do { -- debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls, ppr rhs]) + ; runSpecM dflags this_mod $ + specCalls (Just this_mod) top_env rules_for_fn good_calls fn rhs } ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs] -- After the rules kick in we may get recursion, but -- we rely on a global GlomBinds to sort that out later -- See Note [Glom the bindings if imported functions are specialised] -- Now specialise any cascaded calls - ; (rules2, spec_binds2) <- -- pprTrace "specImport 2" (ppr fn $$ ppr rules1 $$ ppr spec_binds1) $ - specImports dflags this_mod top_env - (extendVarSet done fn) - (fn:callers) - (extendRuleBaseList rb rules1) - uds + -- ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) + ; (rules2, spec_binds2) <- spec_imports dflags this_mod top_env + (fn:callers) + (extendRuleBaseList rb rules1) + (dict_binds `unionBags` dict_binds1) + new_calls - ; let final_binds = spec_binds2 ++ spec_binds1 + ; let final_binds = wrapDictBinds dict_binds1 $ + spec_binds2 ++ spec_binds1 ; return (rules2 ++ rules1, final_binds) } - | otherwise = do { tryWarnMissingSpecs dflags callers fn calls_for_fn - ; return ([], [])} + | otherwise + = do { tryWarnMissingSpecs dflags callers fn good_calls + ; return ([], [])} where unfolding = realIdUnfolding fn -- We want to see the unfolding even for loop breakers + good_calls = filterCalls cis dict_binds + -- SUPER IMPORTANT! Drop calls that (directly or indirectly) refer to fn + -- See Note [Avoiding loops in specImports] -- | Returns whether or not to show a missed-spec warning. -- If -Wall-missed-specializations is on, show the warning. @@ -790,8 +808,114 @@ wantSpecImport dflags unf -- inside it that we want to specialise | otherwise -> False -- Stable, not INLINE, hence INLINABLE -{- Note [Warning about missed specialisations] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Avoiding loops in specImports] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We must take great care when specialising instance declarations +(functions like $fOrdList) lest we accidentally build a recursive +dictionary. See Note [Avoiding loops]. + +The basic strategy of Note [Avoiding loops] is to use filterCalls +to discard loopy specialisations. But to do that we must ensure +that the in-scope dict-binds (passed to filterCalls) contains +all the needed dictionary bindings. In particular, in the recursive +call to spec_imorpts in spec_import, we must include the dict-binds +from the parent. Lacking this caused #17151, a really nasty bug. + +Here is what happened. +* Class struture: + Source is a superclass of Mut + Index is a superclass of Source + +* We started with these dict binds + dSource = $fSourcePix @Int $fIndexInt + dIndex = sc_sel dSource + dMut = $fMutPix @Int dIndex + and these calls to specialise + $fMutPix @Int dIndex + $fSourcePix @Int $fIndexInt + +* We specialised the call ($fMutPix @Int dIndex) + ==> new call ($fSourcePix @Int dIndex) + (because Source is a superclass of Mut) + +* We specialised ($fSourcePix @Int dIndex) + ==> produces specialised dict $s$fSourcePix, + a record with dIndex as a field + plus RULE forall d. ($fSourcePix @Int d) = $s$fSourcePix + *** This is the bogus step *** + +* Now we decide not to specialise the call + $fSourcePix @Int $fIndexInt + because we alredy have a RULE that matches it + +* Finally the simplifer rewrites + dSource = $fSourcePix @Int $fIndexInt + ==> dSource = $s$fSourcePix + +Disaster. Now we have + +Rewrite dSource's RHS to $s$fSourcePix Disaster + dSource = $s$fSourcePix + dIndex = sc_sel dSource + $s$fSourcePix = MkSource dIndex ... + +Solution: filterCalls should have stopped the bogus step, +by seeing that dIndex transitively uses $fSourcePix. But +it can only do that if it sees all the dict_binds. Wow. + +-------------- +Here's another example (#13429). Suppose we have + class Monoid v => C v a where ... + +We start with a call + f @ [Integer] @ Integer $fC[]Integer + +Specialising call to 'f' gives dict bindings + $dMonoid_1 :: Monoid [Integer] + $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer + + $dC_1 :: C [Integer] (Node [Integer] Integer) + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + +...plus a recursive call to + f @ [Integer] @ (Node [Integer] Integer) $dC_1 + +Specialising that call gives + $dMonoid_2 :: Monoid [Integer] + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + + $dC_2 :: C [Integer] (Node [Integer] Integer) + $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 + +Now we have two calls to the imported function + M.$fCvNode :: Monoid v => C v a + M.$fCvNode @v @a m = C m some_fun + +But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) +for specialisation, else we get: + + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + $s$fCvNode = C $dMonoid_2 ... + RULE M.$fCvNode [Integer] _ _ = $s$fCvNode + +Now use the rule to rewrite the call in the RHS of $dC_1 +and we get a loop! + + +Note [specImport call stack] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising an imports function 'f', we may get new calls +of an imported fuction 'g', which we want to specialise in turn, +and similarly specialising 'g' might expose a new call to 'h'. + +We track the stack of enclosing functions. So when specialising 'h' we +haev a specImport call stack of [g,f]. We do this for two reasons: +* Note [Warning about missed specialisations] +* Note [Avoiding recursive specialisation] + +Note [Warning about missed specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose * In module Lib, you carefully mark a function 'foo' INLINABLE * Import Lib(foo) into another module M @@ -807,6 +931,16 @@ is what Opt_WarnAllMissedSpecs does. ToDo: warn about missed opportunities for local functions. +Note [Avoiding recursive specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we specialise 'f' we may find new overloaded calls to 'g', 'h' in +'f's RHS. So we want to specialise g,h. But we don't want to +specialise f any more! It's possible that f's RHS might have a +recursive yet-more-specialised call, so we'd diverge in that case. +And if the call is to the same type, one specialisation is enough. +Avoiding this recursive specialisation loop is one reason for the +'callers' stack passed to specImports and specImport. + Note [Specialise imported INLINABLE things] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ What imported functions do we specialise? The basic set is @@ -842,15 +976,6 @@ make sure that f_spec is recursive. Easiest thing is to make all the specialisations for imported bindings recursive. -Note [Avoiding recursive specialisation] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When we specialise 'f' we may find new overloaded calls to 'g', 'h' in -'f's RHS. So we want to specialise g,h. But we don't want to -specialise f any more! It's possible that f's RHS might have a -recursive yet-more-specialised call, so we'd diverge in that case. -And if the call is to the same type, one specialisation is enough. -Avoiding this recursive specialisation loop is the reason for the -'done' VarSet passed to specImports and specImport. ************************************************************************ * * @@ -992,7 +1117,8 @@ specCase env scrut' case_bndr [(con, args, rhs)] ; (rhs', rhs_uds) <- specExpr env_rhs' rhs ; let scrut_bind = mkDB (NonRec case_bndr_flt scrut') case_bndr_set = unitVarSet case_bndr_flt - sc_binds = [(NonRec sc_arg_flt sc_rhs, case_bndr_set) + sc_binds = [ DB { db_bind = NonRec sc_arg_flt sc_rhs + , db_fvs = case_bndr_set } | (sc_arg_flt, sc_rhs) <- sc_args_flt `zip` sc_rhss ] flt_binds = scrut_bind : sc_binds (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds @@ -1115,7 +1241,7 @@ specBind rhs_env (NonRec fn rhs) body_uds else -- No call in final_uds mentions bound variables, -- so we can just leave the binding here - return (map fst final_binds, free_uds) } + return (map db_bind final_binds, free_uds) } specBind rhs_env (Rec pairs) body_uds @@ -1142,7 +1268,7 @@ specBind rhs_env (Rec pairs) body_uds ; if float_all then return ([], final_uds `snocDictBind` final_bind) else - return ([fst final_bind], final_uds) } + return ([db_bind final_bind], final_uds) } --------------------------- @@ -1621,8 +1747,10 @@ In general, we need only make this Rec if Note [Avoiding loops] ~~~~~~~~~~~~~~~~~~~~~ When specialising /dictionary functions/ we must be very careful to -avoid building loops. Here is an example that bit us badly: #3591 +avoid building loops. Here is an example that bit us badly, on +several distinct occasions. +Here is one: #3591 class Eq a => C a instance Eq [a] => C [a] @@ -1637,13 +1765,11 @@ This translates to None of these definitions is recursive. What happened was that we generated a specialisation: - RULE forall d. dfun T d = dT :: C [T] dT = (MkD a d (meth d)) [T/a, d1/d] = MkD T d1 (meth d1) But now we use the RULE on the RHS of d2, to get - d2 = dT = MkD d1 (meth d1) d1 = $p1 d2 @@ -1660,46 +1786,6 @@ Solution: (directly or indirectly) on the dfun we are specialising. This is done by 'filterCalls' --------------- -Here's another example, this time for an imported dfun, so the call -to filterCalls is in specImports (#13429). Suppose we have - class Monoid v => C v a where ... - -We start with a call - f @ [Integer] @ Integer $fC[]Integer - -Specialising call to 'f' gives dict bindings - $dMonoid_1 :: Monoid [Integer] - $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer - - $dC_1 :: C [Integer] (Node [Integer] Integer) - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - -...plus a recursive call to - f @ [Integer] @ (Node [Integer] Integer) $dC_1 - -Specialising that call gives - $dMonoid_2 :: Monoid [Integer] - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - - $dC_2 :: C [Integer] (Node [Integer] Integer) - $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 - -Now we have two calls to the imported function - M.$fCvNode :: Monoid v => C v a - M.$fCvNode @v @a m = C m some_fun - -But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) -for specialisation, else we get: - - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - $s$fCvNode = C $dMonoid_2 ... - RULE M.$fCvNode [Integer] _ _ = $s$fCvNode - -Now use the rule to rewrite the call in the RHS of $dC_1 -and we get a loop! - -------------- Here's yet another example @@ -2227,7 +2313,7 @@ data UsageDetails -- | A 'DictBind' is a binding along with a cached set containing its free -- variables (both type variables and dictionaries) -type DictBind = (CoreBind, VarSet) +data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet } {- Note [Floated dictionary bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2256,6 +2342,11 @@ So the DictBinds in (ud_binds :: Bag DictBind) may contain non-dictionary bindings too. -} +instance Outputable DictBind where + ppr (DB { db_bind = bind, db_fvs = fvs }) + = text "DB" <+> braces (sep [ text "bind:" <+> ppr bind + , text "fvs: " <+> ppr fvs ]) + instance Outputable UsageDetails where ppr (MkUD { ud_binds = dbs, ud_calls = calls }) = text "MkUD" <+> braces (sep (punctuate comma @@ -2304,8 +2395,8 @@ ppr_call_key_ty (SpecDict _) = Nothing ppr_call_key_ty UnspecArg = Nothing instance Outputable CallInfo where - ppr (CI { ci_key = key, ci_fvs = fvs }) - = text "CI" <> braces (hsep [ fsep (mapMaybe ppr_call_key_ty key), ppr fvs ]) + ppr (CI { ci_key = key, ci_fvs = _fvs }) + = text "CI" <> braces (sep (map ppr key)) unionCalls :: CallDetails -> CallDetails -> CallDetails unionCalls c1 c2 = plusDVarEnv_C unionCallInfoSet c1 c2 @@ -2491,11 +2582,11 @@ plusUDs (MkUD {ud_binds = db1, ud_calls = calls1}) ----------------------------- _dictBindBndrs :: Bag DictBind -> [Id] -_dictBindBndrs dbs = foldr ((++) . bindersOf . fst) [] dbs +_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs -- | Construct a 'DictBind' from a 'CoreBind' mkDB :: CoreBind -> DictBind -mkDB bind = (bind, bind_fvs bind) +mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind } -- | Identify the free variables of a 'CoreBind' bind_fvs :: CoreBind -> VarSet @@ -2526,17 +2617,18 @@ pair_fvs (bndr, rhs) = exprSomeFreeVars interesting rhs -- | Flatten a set of "dumped" 'DictBind's, and some other binding -- pairs, into a single recursive binding. -recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind ->DictBind +recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind -> DictBind recWithDumpedDicts pairs dbs - = (Rec bindings, fvs) + = DB { db_bind = Rec bindings, db_fvs = fvs } where - (bindings, fvs) = foldr add - ([], emptyVarSet) - (dbs `snocBag` mkDB (Rec pairs)) - add (NonRec b r, fvs') (pairs, fvs) = - ((b,r) : pairs, fvs `unionVarSet` fvs') - add (Rec prs1, fvs') (pairs, fvs) = - (prs1 ++ pairs, fvs `unionVarSet` fvs') + (bindings, fvs) = foldr add ([], emptyVarSet) + (dbs `snocBag` mkDB (Rec pairs)) + add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc) + = case bind of + NonRec b r -> ((b,r) : prs_acc, fvs') + Rec prs1 -> (prs1 ++ prs_acc, fvs') + where + fvs' = fvs_acc `unionVarSet` fvs snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails -- Add ud_binds to the tail end of the bindings in uds @@ -2556,13 +2648,13 @@ wrapDictBinds :: Bag DictBind -> [CoreBind] -> [CoreBind] wrapDictBinds dbs binds = foldr add binds dbs where - add (bind,_) binds = bind : binds + add (DB { db_bind = bind }) binds = bind : binds wrapDictBindsE :: Bag DictBind -> CoreExpr -> CoreExpr wrapDictBindsE dbs expr = foldr add expr dbs where - add (bind,_) expr = Let bind expr + add (DB { db_bind = bind }) expr = Let bind expr ---------------------- dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, Bag DictBind) @@ -2624,9 +2716,10 @@ filterCalls (CIS fn call_bag) dbs -- (_,_,dump_set) = splitDictBinds dbs {fn} -- But this variant is shorter - go so_far (db,fvs) | fvs `intersectsVarSet` so_far - = extendVarSetList so_far (bindersOf db) - | otherwise = so_far + go so_far (DB { db_bind = bind, db_fvs = fvs }) + | fvs `intersectsVarSet` so_far + = extendVarSetList so_far (bindersOf bind) + | otherwise = so_far ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) @@ -2643,8 +2736,9 @@ splitDictBinds dbs bndr_set -- Important that it's foldl' not foldr; -- we're accumulating the set of dumped ids in dump_set where - split_db (free_dbs, dump_dbs, dump_idset) db@(bind, fvs) - | dump_idset `intersectsVarSet` fvs -- Dump it + split_db (free_dbs, dump_dbs, dump_idset) db + | DB { db_bind = bind, db_fvs = fvs } <- db + , dump_idset `intersectsVarSet` fvs -- Dump it = (free_dbs, dump_dbs `snocBag` db, extendVarSetList dump_idset (bindersOf bind)) ===================================== testsuite/tests/simplCore/should_run/T17151.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE FlexibleContexts #-} +module Main where + +import T17151a + +main :: IO () +main = do + let ys :: Array P Int Int + ys = computeS (makeArray D 1 (const 5)) + applyStencil :: + (Source P ix Int, Load D ix Int) + => Stencil ix Int Int + -> Array P ix Int + -> Array P ix Int + applyStencil s = computeS . mapStencil s + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) ===================================== testsuite/tests/simplCore/should_run/T17151.stdout ===================================== @@ -0,0 +1,2 @@ +55 +55 ===================================== testsuite/tests/simplCore/should_run/T17151a.hs ===================================== @@ -0,0 +1,205 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE EmptyDataDecls #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +module T17151a + ( computeS + , Stencil + , P(..) + , D(..) + , makeConvolutionStencilFromKernel + , mapStencil + , Array + , Construct(..) + , Source(..) + , Load(..) + , Mutable(..) + ) where + +import Control.Monad.ST +import Data.Functor.Identity +import GHC.STRef +import GHC.ST +import GHC.Exts +import Unsafe.Coerce +import Data.Kind + +---- Hacked up stuff to simulate primitive package +class Prim e where + indexByteArray :: ByteArray -> Int -> e + sizeOf :: e ->Int +instance Prim Int where + indexByteArray _ _ = 55 + sizeOf _ = 99 + +data ByteArray = BA +type MutableByteArray s = STRef s Int + +class Monad m => PrimMonad m where + type PrimState m + primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a +instance PrimMonad (ST s) where + type PrimState (ST s) = s + primitive = ST + +unsafeFreezeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> m ByteArray +unsafeFreezeByteArray a = return (unsafeCoerce a) + +newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m)) +newByteArray (I# n#) + = primitive (\s# -> case newMutVar# 33 s# of + (# s'#, arr# #) -> (# s'#, STRef arr# #)) + +writeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> e -> m () +writeByteArray _ _ _ = return () + +----- End of hacked up stuff + +-------------- +newtype Stencil ix e a = + Stencil ((ix -> e) -> ix -> a) + +mapStencil :: Source r ix e => Stencil ix e a -> Array r ix e -> Array D ix a +mapStencil (Stencil stencilF) arr = DArray (size arr) (stencilF (unsafeIndex arr)) +{-# INLINE mapStencil #-} + +makeConvolutionStencilFromKernel + :: (Source r ix e, Num e) + => Array r ix e + -> Stencil ix e e +makeConvolutionStencilFromKernel arr = Stencil stencil + where + sz = size arr + sCenter = liftIndex (`quot` 2) sz + stencil getVal ix = + runIdentity $ + loopM 0 (< totalElem sz) (+ 1) 0 $ \i a -> + pure $ accum a (fromLinearIndex sz i) (unsafeLinearIndex arr i) + where + ixOff = liftIndex2 (+) ix sCenter + accum acc kIx kVal = getVal (liftIndex2 (-) ixOff kIx) * kVal + acc + {-# INLINE accum #-} + {-# INLINE stencil #-} +{-# INLINE makeConvolutionStencilFromKernel #-} + + +computeS :: (Mutable r ix e, Load r' ix e) => Array r' ix e -> Array r ix e +computeS arr = runST $ do + marr <- unsafeNew (size arr) + unsafeLoadIntoS marr arr + unsafeFreeze marr +{-# INLINE computeS #-} + + +data D = D deriving Show + +data instance Array D ix e = DArray{dSize :: ix, + dIndex :: ix -> e} + +instance Index ix => Construct D ix e where + makeArray _ = DArray + {-# INLINE makeArray #-} + +instance Index ix => Source D ix e where + unsafeIndex = dIndex + {-# INLINE unsafeIndex #-} + +instance Index ix => Load D ix e where + size = dSize + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +data P = P deriving Show + +data instance Array P ix e = PArray ix ByteArray + +instance (Prim e, Index ix) => Construct P ix e where + makeArray _ sz f = computeS (makeArray D sz f) + {-# INLINE makeArray #-} + +instance (Prim e, Index ix) => Source P ix e where + unsafeIndex (PArray sz a) = indexByteArray a . toLinearIndex sz + {-# INLINE unsafeIndex #-} + +instance (Prim e, Index ix) => Mutable P ix e where + data MArray s P ix e = MPArray ix (MutableByteArray s) + unsafeFreeze (MPArray sz a) = PArray sz <$> unsafeFreezeByteArray a + {-# INLINE unsafeFreeze #-} + unsafeNew sz = MPArray sz <$> newByteArray (totalElem sz * eSize) + where + eSize = sizeOf (undefined :: e) + {-# INLINE unsafeNew #-} + unsafeLinearWrite (MPArray _ ma) = writeByteArray ma + {-# INLINE unsafeLinearWrite #-} + + +instance (Prim e, Index ix) => Load P ix e where + size (PArray sz _) = sz + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +unsafeLinearIndex :: Source r ix e => Array r ix e -> Int -> e +unsafeLinearIndex arr = unsafeIndex arr . fromLinearIndex (size arr) +{-# INLINE unsafeLinearIndex #-} + + +loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a +loopM init' condition increment initAcc f = go init' initAcc + where + go step acc + | condition step = f step acc >>= go (increment step) + | otherwise = return acc +{-# INLINE loopM #-} + +splitLinearlyWith_ :: + Monad m => Int -> (Int -> b) -> (Int -> b -> m ()) -> m () +splitLinearlyWith_ totalLength index write = + loopM 0 (< totalLength) (+1) () $ \i () -> write i (index i) +{-# INLINE splitLinearlyWith_ #-} + + +data family Array r ix e :: Type + +class Index ix => Construct r ix e where + makeArray :: r -> ix -> (ix -> e) -> Array r ix e + +class Load r ix e => Source r ix e where + unsafeIndex :: Array r ix e -> ix -> e + +class Index ix => Load r ix e where + size :: Array r ix e -> ix + loadArrayM :: Monad m => Array r ix e -> (Int -> e -> m ()) -> m () + unsafeLoadIntoS :: + (Mutable r' ix e, PrimMonad m) => MArray (PrimState m) r' ix e -> Array r ix e -> m () + unsafeLoadIntoS marr arr = loadArrayM arr (unsafeLinearWrite marr) + {-# INLINE unsafeLoadIntoS #-} + +class (Construct r ix e, Source r ix e) => Mutable r ix e where + data MArray s r ix e :: Type + unsafeFreeze :: PrimMonad m => MArray (PrimState m) r ix e -> m (Array r ix e) + unsafeNew :: PrimMonad m => ix -> m (MArray (PrimState m) r ix e) + unsafeLinearWrite :: PrimMonad m => MArray (PrimState m) r ix e -> Int -> e -> m () + + +class (Eq ix, Ord ix, Show ix) => + Index ix + where + totalElem :: ix -> Int + liftIndex2 :: (Int -> Int -> Int) -> ix -> ix -> ix + liftIndex :: (Int -> Int) -> ix -> ix + toLinearIndex :: ix -> ix -> Int + fromLinearIndex :: ix -> Int -> ix + +instance Index Int where + totalElem = id + toLinearIndex _ = id + fromLinearIndex _ = id + liftIndex f = f + liftIndex2 f = f ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -92,3 +92,4 @@ test('T15840', normal, compile_and_run, ['']) test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) +test('T17151', [], multimod_compile_and_run, ['T17151', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dcfe29c8520244764146c7a5f336be1f9700db6c...e850d14ffbeea39ad386b1e888cd97375758d6d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dcfe29c8520244764146c7a5f336be1f9700db6c...e850d14ffbeea39ad386b1e888cd97375758d6d6 You're receiving 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 6 18:01:21 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 06 Apr 2020 14:01:21 -0400 Subject: [Git][ghc/ghc][wip/andreask/large_address_space] Enable large address space optimization on windows. Message-ID: <5e8b6e712df4c_616713503ee032774c0@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/large_address_space at Glasgow Haskell Compiler / GHC Commits: c5dfc76e by Andreas Klebinger at 2020-04-06T20:00:58+02:00 Enable large address space optimization on windows. Starting with Win 8.1/Server 2012 windows no longer preallocates page tables for reserverd memory eagerly, which prevented us from using this approach in the past. - - - - - 2 changed files: - configure.ac - docs/users_guide/8.12.1-notes.rst Changes: ===================================== configure.ac ===================================== @@ -1203,11 +1203,15 @@ if test "$ac_cv_sizeof_void_p" -eq 8 ; then if test "x$EnableLargeAddressSpace" = "xyes" ; then if test "$ghc_host_os" = "darwin" ; then use_large_address_space=yes - elif test "$ghc_host_os" = "openbsd" ; then - # as of OpenBSD 5.8 (2015), OpenBSD does not support mmap with MAP_NORESERVE. - # The flag MAP_NORESERVE is supported for source compatibility reasons, - # but is completely ignored by OS mmap - use_large_address_space=no + elif test "$ghc_host_os" = "openbsd" ; then + # as of OpenBSD 5.8 (2015), OpenBSD does not support mmap with MAP_NORESERVE. + # The flag MAP_NORESERVE is supported for source compatibility reasons, + # but is completely ignored by OS mmap + use_large_address_space=no + elif test "$ghc_host_os" = "mingw32" ; then + # as of Windows 8.1/Server 2012 windows does no longer allocate the page + # tabe for reserved memory eagerly. So we are now free to use LAS there too. + use_large_address_space=yes else AC_CHECK_DECLS([MAP_NORESERVE, MADV_FREE, MADV_DONTNEED],[],[], [ ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -40,7 +40,7 @@ Language There is a chance we will tweak the lookup scheme in the future, to make this workaround unnecessary. - + Compiler ~~~~~~~~ @@ -52,6 +52,9 @@ GHCi Runtime system ~~~~~~~~~~~~~~ + - Windows now uses the large address space allocator by default. + In extreme cases we saw improvements by up to 3% decreased runtime. + Template Haskell ~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c5dfc76e084225fc305c130b9c85069ee087e6ed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c5dfc76e084225fc305c130b9c85069ee087e6ed You're receiving 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 6 18:05:12 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 06 Apr 2020 14:05:12 -0400 Subject: [Git][ghc/ghc][wip/andreask/large_address_space] Enable large address space optimization on windows. Message-ID: <5e8b6f586d7ea_616776d1c7432779dd@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/large_address_space at Glasgow Haskell Compiler / GHC Commits: 3be40803 by Andreas Klebinger at 2020-04-06T20:04:55+02:00 Enable large address space optimization on windows. Starting with Win 8.1/Server 2012 windows no longer preallocates page tables for reserverd memory eagerly, which prevented us from using this approach in the past. - - - - - 2 changed files: - configure.ac - docs/users_guide/8.12.1-notes.rst Changes: ===================================== configure.ac ===================================== @@ -1203,11 +1203,15 @@ if test "$ac_cv_sizeof_void_p" -eq 8 ; then if test "x$EnableLargeAddressSpace" = "xyes" ; then if test "$ghc_host_os" = "darwin" ; then use_large_address_space=yes - elif test "$ghc_host_os" = "openbsd" ; then - # as of OpenBSD 5.8 (2015), OpenBSD does not support mmap with MAP_NORESERVE. - # The flag MAP_NORESERVE is supported for source compatibility reasons, - # but is completely ignored by OS mmap - use_large_address_space=no + elif test "$ghc_host_os" = "openbsd" ; then + # as of OpenBSD 5.8 (2015), OpenBSD does not support mmap with MAP_NORESERVE. + # The flag MAP_NORESERVE is supported for source compatibility reasons, + # but is completely ignored by OS mmap + use_large_address_space=no + elif test "$ghc_host_os" = "mingw32" ; then + # as of Windows 8.1/Server 2012 windows does no longer allocate the page + # tabe for reserved memory eagerly. So we are now free to use LAS there too. + use_large_address_space=yes else AC_CHECK_DECLS([MAP_NORESERVE, MADV_FREE, MADV_DONTNEED],[],[], [ ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -40,7 +40,7 @@ Language There is a chance we will tweak the lookup scheme in the future, to make this workaround unnecessary. - + Compiler ~~~~~~~~ @@ -52,6 +52,12 @@ GHCi Runtime system ~~~~~~~~~~~~~~ + - Windows now uses the large address space allocator by default. + In extreme cases we saw improvements by up to 3% decreased runtime. + + The downside is that haskell apps run on older (Pre Win-8.1/Server 2012) + systems will have higher memory footprints. + Template Haskell ~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3be4080346729d966b10160100b4025b7bb6bd8b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3be4080346729d966b10160100b4025b7bb6bd8b You're receiving 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 6 19:13:13 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 06 Apr 2020 15:13:13 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] 16 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e8b7f4970141_616713503ee03284693@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - 7ed49ad8 by Sebastian Graf at 2020-04-06T21:13:02+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 7e6b8aa2 by Sebastian Graf at 2020-04-06T21:13:02+02:00 Fix the perf regression - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8ae14a25c07748b23f79dd67cfd01b8f814ff9da...7e6b8aa2cb9ec852229b3d3db9b40b7e8a9a0e2a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8ae14a25c07748b23f79dd67cfd01b8f814ff9da...7e6b8aa2cb9ec852229b3d3db9b40b7e8a9a0e2a You're receiving 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 6 20:19:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 06 Apr 2020 16:19:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Don't override proc CafInfos in ticky builds Message-ID: <5e8b8ee8ddb27_61677c82e0c33109af@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - c2d2b7f1 by Daniel Gröber at 2020-04-06T16:19:30-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - b305c466 by Sebastian Graf at 2020-04-06T16:19:30-04:00 Re-export GHC.Magic.noinline from base - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Op/Specialise.hs - libraries/base/GHC/Exts.hs - rts/ProfHeap.c - + testsuite/tests/simplCore/should_run/T17151.hs - + testsuite/tests/simplCore/should_run/T17151.stdout - + testsuite/tests/simplCore/should_run/T17151a.hs - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -108,7 +108,7 @@ module GHC.Cmm.CLabel ( pprCLabel, isInfoTableLabel, isConInfoTableLabel, - isIdLabel + isIdLabel, isTickyLabel ) where #include "HsVersions.h" @@ -268,6 +268,12 @@ isIdLabel :: CLabel -> Bool isIdLabel IdLabel{} = True isIdLabel _ = False +-- Used in SRT analysis. See Note [Ticky labels in SRT analysis] in +-- GHC.Cmm.Info.Build. +isTickyLabel :: CLabel -> Bool +isTickyLabel (IdLabel _ _ RednCounts) = True +isTickyLabel _ = False + -- This is laborious, but necessary. We can't derive Ord because -- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the -- implementation. See Note [No Ord for Unique] @@ -462,8 +468,7 @@ mkSRTLabel :: Unique -> CLabel mkSRTLabel u = SRTLabel u mkRednCountsLabel :: Name -> CLabel -mkRednCountsLabel name = - IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] +mkRednCountsLabel name = IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] -- These have local & (possibly) external variants: mkLocalClosureLabel :: Name -> CafInfo -> CLabel ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -409,6 +409,30 @@ Maybe, but could you prove that RET_FUN is the only way that resurrection can occur? So, no shortcutting. + +Note [Ticky labels in SRT analysis] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Raw Cmm data (CmmStaticsRaw) can't contain pointers so they're considered +non-CAFFY in SRT analysis and we update the SRTMap mapping them to `Nothing` +(meaning they're not CAFFY). + +However when building with -ticky we generate ticky CLabels using the function's +`Name`. For example, if we have a top-level function `sat_s1rQ`, in a ticky +build we get two IdLabels using the name `sat_s1rQ`: + +- For the function itself: IdLabel sat_s1rQ ... Entry +- For the ticky counter: IdLabel sat_s1rQ ... RednCounts + +In these cases we really want to use the function definition for the SRT +analysis of this Name, because that's what we export for this Name -- ticky +counters are not exported. So we ignore ticky counters in SRT analysis (which +are never CAFFY and never exported). + +Not doing this caused #17947 where we analysed the function first mapped the +name to CAFFY. We then saw the ticky constructor, and becuase it has the same +Name as the function and is not CAFFY we overrode the CafInfo of the name as +non-CAFFY. -} -- --------------------------------------------------------------------- @@ -818,8 +842,11 @@ doSRTs dflags moduleSRTInfo procs data_ = do -- already updated by oneSRT srtMap CmmData _ (CmmStaticsRaw lbl _) - | isIdLabel lbl -> - -- not analysed by oneSRT, declare it non-CAFFY here + | isIdLabel lbl && not (isTickyLabel lbl) -> + -- Raw data are not analysed by oneSRT and they can't + -- be CAFFY. + -- See Note [Ticky labels in SRT analysis] above for + -- why we exclude ticky labels here. Map.insert (mkCAFLabel lbl) Nothing srtMap | otherwise -> -- Not an IdLabel, ignore ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -589,19 +589,11 @@ specProgram guts@(ModGuts { mg_module = this_mod -- Specialise the bindings of this module ; (binds', uds) <- runSpecM dflags this_mod (go binds) - -- Specialise imported functions - ; hpt_rules <- getRuleBase - ; let rule_base = extendRuleBaseList hpt_rules local_rules - ; (new_rules, spec_binds) <- specImports dflags this_mod top_env emptyVarSet - [] rule_base uds - - ; let final_binds - | null spec_binds = binds' - | otherwise = Rec (flattenBinds spec_binds) : binds' - -- Note [Glom the bindings if imported functions are specialised] + ; (spec_rules, spec_binds) <- specImports dflags this_mod top_env + local_rules uds - ; return (guts { mg_binds = final_binds - , mg_rules = new_rules ++ local_rules }) } + ; return (guts { mg_binds = spec_binds ++ binds' + , mg_rules = spec_rules ++ local_rules }) } where -- We need to start with a Subst that knows all the things -- that are in scope, so that the substitution engine doesn't @@ -645,72 +637,93 @@ See #10491 * * ********************************************************************* -} --- | Specialise a set of calls to imported bindings -specImports :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these ones - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module and the home package - -- (but not external packages, which can change) - -> UsageDetails -- Calls for imported things, and floating bindings - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings - -- See Note [Wrapping bindings returned by specImports] -specImports dflags this_mod top_env done callers rule_base +specImports :: DynFlags -> Module -> SpecEnv + -> [CoreRule] + -> UsageDetails + -> CoreM ([CoreRule], [CoreBind]) +specImports dflags this_mod top_env local_rules (MkUD { ud_binds = dict_binds, ud_calls = calls }) - -- See Note [Disabling cross-module specialisation] | not $ gopt Opt_CrossModuleSpecialise dflags - = return ([], []) + -- See Note [Disabling cross-module specialisation] + = return ([], wrapDictBinds dict_binds []) | otherwise - = do { let import_calls = dVarEnvElts calls - ; (rules, spec_binds) <- go rule_base import_calls + = do { hpt_rules <- getRuleBase + ; let rule_base = extendRuleBaseList hpt_rules local_rules + + ; (spec_rules, spec_binds) <- spec_imports dflags this_mod top_env + [] rule_base + dict_binds calls -- Don't forget to wrap the specialized bindings with -- bindings for the needed dictionaries. -- See Note [Wrap bindings returned by specImports] - ; let spec_binds' = wrapDictBinds dict_binds spec_binds + -- and Note [Glom the bindings if imported functions are specialised] + ; let final_binds + | null spec_binds = wrapDictBinds dict_binds [] + | otherwise = [Rec $ flattenBinds $ + wrapDictBinds dict_binds spec_binds] + + ; return (spec_rules, final_binds) + } + +-- | Specialise a set of calls to imported bindings +spec_imports :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module and the home package + -- (but not external packages, which can change) + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallDetails -- Calls for imported things + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_imports dflags this_mod top_env + callers rule_base dict_binds calls + = do { let import_calls = dVarEnvElts calls + -- ; debugTraceMsg (text "specImports {" <+> + -- vcat [ text "calls:" <+> ppr import_calls + -- , text "dict_binds:" <+> ppr dict_binds ]) + ; (rules, spec_binds) <- go rule_base import_calls + -- ; debugTraceMsg (text "End specImports }" <+> ppr import_calls) - ; return (rules, spec_binds') } + ; return (rules, spec_binds) } where go :: RuleBase -> [CallInfoSet] -> CoreM ([CoreRule], [CoreBind]) go _ [] = return ([], []) - go rb (cis@(CIS fn _) : other_calls) - = do { let ok_calls = filterCalls cis dict_binds - -- Drop calls that (directly or indirectly) refer to fn - -- See Note [Avoiding loops] --- ; debugTraceMsg (text "specImport" <+> vcat [ ppr fn --- , text "calls" <+> ppr cis --- , text "ud_binds =" <+> ppr dict_binds --- , text "dump set =" <+> ppr dump_set --- , text "filtered calls =" <+> ppr ok_calls ]) - ; (rules1, spec_binds1) <- specImport dflags this_mod top_env - done callers rb fn ok_calls + go rb (cis : other_calls) + = do { -- debugTraceMsg (text "specImport {" <+> ppr cis) + ; (rules1, spec_binds1) <- spec_import dflags this_mod top_env + callers rb dict_binds cis + -- ; debugTraceMsg (text "specImport }" <+> ppr cis) ; (rules2, spec_binds2) <- go (extendRuleBaseList rb rules1) other_calls ; return (rules1 ++ rules2, spec_binds1 ++ spec_binds2) } -specImport :: DynFlags - -> Module - -> SpecEnv -- Passed in so that all top-level Ids are in scope - -> VarSet -- Don't specialise these - -- See Note [Avoiding recursive specialisation] - -> [Id] -- Stack of imported functions being specialised - -> RuleBase -- Rules from this module - -> Id -> [CallInfo] -- Imported function and calls for it - -> CoreM ( [CoreRule] -- New rules - , [CoreBind] ) -- Specialised bindings -specImport dflags this_mod top_env done callers rb fn calls_for_fn - | fn `elemVarSet` done +spec_import :: DynFlags + -> Module + -> SpecEnv -- Passed in so that all top-level Ids are in scope + -> [Id] -- Stack of imported functions being specialised + -- See Note [specImport call stack] + -> RuleBase -- Rules from this module + -> Bag DictBind -- Dict bindings, used /only/ for filterCalls + -- See Note [Avoiding loops in specImports] + -> CallInfoSet -- Imported function and calls for it + -> CoreM ( [CoreRule] -- New rules + , [CoreBind] ) -- Specialised bindings +spec_import dflags this_mod top_env callers + rb dict_binds cis@(CIS fn _) + | isIn "specImport" fn callers = return ([], []) -- No warning. This actually happens all the time -- when specialising a recursive function, because -- the RHS of the specialised function contains a recursive -- call to the original function - | null calls_for_fn -- We filtered out all the calls in deleteCallsMentioning - = return ([], []) + | null good_calls + = do { -- debugTraceMsg (text "specImport:no valid calls") + ; return ([], []) } | wantSpecImport dflags unfolding , Just rhs <- maybeUnfoldingTemplate unfolding @@ -723,32 +736,37 @@ specImport dflags this_mod top_env done callers rb fn calls_for_fn ; let full_rb = unionRuleBase rb (eps_rule_base eps) rules_for_fn = getRules (RuleEnv full_rb vis_orphs) fn - ; (rules1, spec_pairs, uds) - <- -- pprTrace "specImport1" (vcat [ppr fn, ppr calls_for_fn, ppr rhs]) $ - runSpecM dflags this_mod $ - specCalls (Just this_mod) top_env rules_for_fn calls_for_fn fn rhs + ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls }) + <- do { -- debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls, ppr rhs]) + ; runSpecM dflags this_mod $ + specCalls (Just this_mod) top_env rules_for_fn good_calls fn rhs } ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs] -- After the rules kick in we may get recursion, but -- we rely on a global GlomBinds to sort that out later -- See Note [Glom the bindings if imported functions are specialised] -- Now specialise any cascaded calls - ; (rules2, spec_binds2) <- -- pprTrace "specImport 2" (ppr fn $$ ppr rules1 $$ ppr spec_binds1) $ - specImports dflags this_mod top_env - (extendVarSet done fn) - (fn:callers) - (extendRuleBaseList rb rules1) - uds + -- ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) + ; (rules2, spec_binds2) <- spec_imports dflags this_mod top_env + (fn:callers) + (extendRuleBaseList rb rules1) + (dict_binds `unionBags` dict_binds1) + new_calls - ; let final_binds = spec_binds2 ++ spec_binds1 + ; let final_binds = wrapDictBinds dict_binds1 $ + spec_binds2 ++ spec_binds1 ; return (rules2 ++ rules1, final_binds) } - | otherwise = do { tryWarnMissingSpecs dflags callers fn calls_for_fn - ; return ([], [])} + | otherwise + = do { tryWarnMissingSpecs dflags callers fn good_calls + ; return ([], [])} where unfolding = realIdUnfolding fn -- We want to see the unfolding even for loop breakers + good_calls = filterCalls cis dict_binds + -- SUPER IMPORTANT! Drop calls that (directly or indirectly) refer to fn + -- See Note [Avoiding loops in specImports] -- | Returns whether or not to show a missed-spec warning. -- If -Wall-missed-specializations is on, show the warning. @@ -790,8 +808,114 @@ wantSpecImport dflags unf -- inside it that we want to specialise | otherwise -> False -- Stable, not INLINE, hence INLINABLE -{- Note [Warning about missed specialisations] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Avoiding loops in specImports] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We must take great care when specialising instance declarations +(functions like $fOrdList) lest we accidentally build a recursive +dictionary. See Note [Avoiding loops]. + +The basic strategy of Note [Avoiding loops] is to use filterCalls +to discard loopy specialisations. But to do that we must ensure +that the in-scope dict-binds (passed to filterCalls) contains +all the needed dictionary bindings. In particular, in the recursive +call to spec_imorpts in spec_import, we must include the dict-binds +from the parent. Lacking this caused #17151, a really nasty bug. + +Here is what happened. +* Class struture: + Source is a superclass of Mut + Index is a superclass of Source + +* We started with these dict binds + dSource = $fSourcePix @Int $fIndexInt + dIndex = sc_sel dSource + dMut = $fMutPix @Int dIndex + and these calls to specialise + $fMutPix @Int dIndex + $fSourcePix @Int $fIndexInt + +* We specialised the call ($fMutPix @Int dIndex) + ==> new call ($fSourcePix @Int dIndex) + (because Source is a superclass of Mut) + +* We specialised ($fSourcePix @Int dIndex) + ==> produces specialised dict $s$fSourcePix, + a record with dIndex as a field + plus RULE forall d. ($fSourcePix @Int d) = $s$fSourcePix + *** This is the bogus step *** + +* Now we decide not to specialise the call + $fSourcePix @Int $fIndexInt + because we alredy have a RULE that matches it + +* Finally the simplifer rewrites + dSource = $fSourcePix @Int $fIndexInt + ==> dSource = $s$fSourcePix + +Disaster. Now we have + +Rewrite dSource's RHS to $s$fSourcePix Disaster + dSource = $s$fSourcePix + dIndex = sc_sel dSource + $s$fSourcePix = MkSource dIndex ... + +Solution: filterCalls should have stopped the bogus step, +by seeing that dIndex transitively uses $fSourcePix. But +it can only do that if it sees all the dict_binds. Wow. + +-------------- +Here's another example (#13429). Suppose we have + class Monoid v => C v a where ... + +We start with a call + f @ [Integer] @ Integer $fC[]Integer + +Specialising call to 'f' gives dict bindings + $dMonoid_1 :: Monoid [Integer] + $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer + + $dC_1 :: C [Integer] (Node [Integer] Integer) + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + +...plus a recursive call to + f @ [Integer] @ (Node [Integer] Integer) $dC_1 + +Specialising that call gives + $dMonoid_2 :: Monoid [Integer] + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + + $dC_2 :: C [Integer] (Node [Integer] Integer) + $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 + +Now we have two calls to the imported function + M.$fCvNode :: Monoid v => C v a + M.$fCvNode @v @a m = C m some_fun + +But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) +for specialisation, else we get: + + $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 + $dMonoid_2 = M.$p1C @ [Integer] $dC_1 + $s$fCvNode = C $dMonoid_2 ... + RULE M.$fCvNode [Integer] _ _ = $s$fCvNode + +Now use the rule to rewrite the call in the RHS of $dC_1 +and we get a loop! + + +Note [specImport call stack] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising an imports function 'f', we may get new calls +of an imported fuction 'g', which we want to specialise in turn, +and similarly specialising 'g' might expose a new call to 'h'. + +We track the stack of enclosing functions. So when specialising 'h' we +haev a specImport call stack of [g,f]. We do this for two reasons: +* Note [Warning about missed specialisations] +* Note [Avoiding recursive specialisation] + +Note [Warning about missed specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose * In module Lib, you carefully mark a function 'foo' INLINABLE * Import Lib(foo) into another module M @@ -807,6 +931,16 @@ is what Opt_WarnAllMissedSpecs does. ToDo: warn about missed opportunities for local functions. +Note [Avoiding recursive specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we specialise 'f' we may find new overloaded calls to 'g', 'h' in +'f's RHS. So we want to specialise g,h. But we don't want to +specialise f any more! It's possible that f's RHS might have a +recursive yet-more-specialised call, so we'd diverge in that case. +And if the call is to the same type, one specialisation is enough. +Avoiding this recursive specialisation loop is one reason for the +'callers' stack passed to specImports and specImport. + Note [Specialise imported INLINABLE things] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ What imported functions do we specialise? The basic set is @@ -842,15 +976,6 @@ make sure that f_spec is recursive. Easiest thing is to make all the specialisations for imported bindings recursive. -Note [Avoiding recursive specialisation] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When we specialise 'f' we may find new overloaded calls to 'g', 'h' in -'f's RHS. So we want to specialise g,h. But we don't want to -specialise f any more! It's possible that f's RHS might have a -recursive yet-more-specialised call, so we'd diverge in that case. -And if the call is to the same type, one specialisation is enough. -Avoiding this recursive specialisation loop is the reason for the -'done' VarSet passed to specImports and specImport. ************************************************************************ * * @@ -992,7 +1117,8 @@ specCase env scrut' case_bndr [(con, args, rhs)] ; (rhs', rhs_uds) <- specExpr env_rhs' rhs ; let scrut_bind = mkDB (NonRec case_bndr_flt scrut') case_bndr_set = unitVarSet case_bndr_flt - sc_binds = [(NonRec sc_arg_flt sc_rhs, case_bndr_set) + sc_binds = [ DB { db_bind = NonRec sc_arg_flt sc_rhs + , db_fvs = case_bndr_set } | (sc_arg_flt, sc_rhs) <- sc_args_flt `zip` sc_rhss ] flt_binds = scrut_bind : sc_binds (free_uds, dumped_dbs) = dumpUDs (case_bndr':args') rhs_uds @@ -1115,7 +1241,7 @@ specBind rhs_env (NonRec fn rhs) body_uds else -- No call in final_uds mentions bound variables, -- so we can just leave the binding here - return (map fst final_binds, free_uds) } + return (map db_bind final_binds, free_uds) } specBind rhs_env (Rec pairs) body_uds @@ -1142,7 +1268,7 @@ specBind rhs_env (Rec pairs) body_uds ; if float_all then return ([], final_uds `snocDictBind` final_bind) else - return ([fst final_bind], final_uds) } + return ([db_bind final_bind], final_uds) } --------------------------- @@ -1621,8 +1747,10 @@ In general, we need only make this Rec if Note [Avoiding loops] ~~~~~~~~~~~~~~~~~~~~~ When specialising /dictionary functions/ we must be very careful to -avoid building loops. Here is an example that bit us badly: #3591 +avoid building loops. Here is an example that bit us badly, on +several distinct occasions. +Here is one: #3591 class Eq a => C a instance Eq [a] => C [a] @@ -1637,13 +1765,11 @@ This translates to None of these definitions is recursive. What happened was that we generated a specialisation: - RULE forall d. dfun T d = dT :: C [T] dT = (MkD a d (meth d)) [T/a, d1/d] = MkD T d1 (meth d1) But now we use the RULE on the RHS of d2, to get - d2 = dT = MkD d1 (meth d1) d1 = $p1 d2 @@ -1660,46 +1786,6 @@ Solution: (directly or indirectly) on the dfun we are specialising. This is done by 'filterCalls' --------------- -Here's another example, this time for an imported dfun, so the call -to filterCalls is in specImports (#13429). Suppose we have - class Monoid v => C v a where ... - -We start with a call - f @ [Integer] @ Integer $fC[]Integer - -Specialising call to 'f' gives dict bindings - $dMonoid_1 :: Monoid [Integer] - $dMonoid_1 = M.$p1C @ [Integer] $fC[]Integer - - $dC_1 :: C [Integer] (Node [Integer] Integer) - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - -...plus a recursive call to - f @ [Integer] @ (Node [Integer] Integer) $dC_1 - -Specialising that call gives - $dMonoid_2 :: Monoid [Integer] - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - - $dC_2 :: C [Integer] (Node [Integer] Integer) - $dC_2 = M.$fCvNode @ [Integer] $dMonoid_2 - -Now we have two calls to the imported function - M.$fCvNode :: Monoid v => C v a - M.$fCvNode @v @a m = C m some_fun - -But we must /not/ use the call (M.$fCvNode @ [Integer] $dMonoid_2) -for specialisation, else we get: - - $dC_1 = M.$fCvNode @ [Integer] $dMonoid_1 - $dMonoid_2 = M.$p1C @ [Integer] $dC_1 - $s$fCvNode = C $dMonoid_2 ... - RULE M.$fCvNode [Integer] _ _ = $s$fCvNode - -Now use the rule to rewrite the call in the RHS of $dC_1 -and we get a loop! - -------------- Here's yet another example @@ -2227,7 +2313,7 @@ data UsageDetails -- | A 'DictBind' is a binding along with a cached set containing its free -- variables (both type variables and dictionaries) -type DictBind = (CoreBind, VarSet) +data DictBind = DB { db_bind :: CoreBind, db_fvs :: VarSet } {- Note [Floated dictionary bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2256,6 +2342,11 @@ So the DictBinds in (ud_binds :: Bag DictBind) may contain non-dictionary bindings too. -} +instance Outputable DictBind where + ppr (DB { db_bind = bind, db_fvs = fvs }) + = text "DB" <+> braces (sep [ text "bind:" <+> ppr bind + , text "fvs: " <+> ppr fvs ]) + instance Outputable UsageDetails where ppr (MkUD { ud_binds = dbs, ud_calls = calls }) = text "MkUD" <+> braces (sep (punctuate comma @@ -2304,8 +2395,8 @@ ppr_call_key_ty (SpecDict _) = Nothing ppr_call_key_ty UnspecArg = Nothing instance Outputable CallInfo where - ppr (CI { ci_key = key, ci_fvs = fvs }) - = text "CI" <> braces (hsep [ fsep (mapMaybe ppr_call_key_ty key), ppr fvs ]) + ppr (CI { ci_key = key, ci_fvs = _fvs }) + = text "CI" <> braces (sep (map ppr key)) unionCalls :: CallDetails -> CallDetails -> CallDetails unionCalls c1 c2 = plusDVarEnv_C unionCallInfoSet c1 c2 @@ -2491,11 +2582,11 @@ plusUDs (MkUD {ud_binds = db1, ud_calls = calls1}) ----------------------------- _dictBindBndrs :: Bag DictBind -> [Id] -_dictBindBndrs dbs = foldr ((++) . bindersOf . fst) [] dbs +_dictBindBndrs dbs = foldr ((++) . bindersOf . db_bind) [] dbs -- | Construct a 'DictBind' from a 'CoreBind' mkDB :: CoreBind -> DictBind -mkDB bind = (bind, bind_fvs bind) +mkDB bind = DB { db_bind = bind, db_fvs = bind_fvs bind } -- | Identify the free variables of a 'CoreBind' bind_fvs :: CoreBind -> VarSet @@ -2526,17 +2617,18 @@ pair_fvs (bndr, rhs) = exprSomeFreeVars interesting rhs -- | Flatten a set of "dumped" 'DictBind's, and some other binding -- pairs, into a single recursive binding. -recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind ->DictBind +recWithDumpedDicts :: [(Id,CoreExpr)] -> Bag DictBind -> DictBind recWithDumpedDicts pairs dbs - = (Rec bindings, fvs) + = DB { db_bind = Rec bindings, db_fvs = fvs } where - (bindings, fvs) = foldr add - ([], emptyVarSet) - (dbs `snocBag` mkDB (Rec pairs)) - add (NonRec b r, fvs') (pairs, fvs) = - ((b,r) : pairs, fvs `unionVarSet` fvs') - add (Rec prs1, fvs') (pairs, fvs) = - (prs1 ++ pairs, fvs `unionVarSet` fvs') + (bindings, fvs) = foldr add ([], emptyVarSet) + (dbs `snocBag` mkDB (Rec pairs)) + add (DB { db_bind = bind, db_fvs = fvs }) (prs_acc, fvs_acc) + = case bind of + NonRec b r -> ((b,r) : prs_acc, fvs') + Rec prs1 -> (prs1 ++ prs_acc, fvs') + where + fvs' = fvs_acc `unionVarSet` fvs snocDictBinds :: UsageDetails -> [DictBind] -> UsageDetails -- Add ud_binds to the tail end of the bindings in uds @@ -2556,13 +2648,13 @@ wrapDictBinds :: Bag DictBind -> [CoreBind] -> [CoreBind] wrapDictBinds dbs binds = foldr add binds dbs where - add (bind,_) binds = bind : binds + add (DB { db_bind = bind }) binds = bind : binds wrapDictBindsE :: Bag DictBind -> CoreExpr -> CoreExpr wrapDictBindsE dbs expr = foldr add expr dbs where - add (bind,_) expr = Let bind expr + add (DB { db_bind = bind }) expr = Let bind expr ---------------------- dumpUDs :: [CoreBndr] -> UsageDetails -> (UsageDetails, Bag DictBind) @@ -2624,9 +2716,10 @@ filterCalls (CIS fn call_bag) dbs -- (_,_,dump_set) = splitDictBinds dbs {fn} -- But this variant is shorter - go so_far (db,fvs) | fvs `intersectsVarSet` so_far - = extendVarSetList so_far (bindersOf db) - | otherwise = so_far + go so_far (DB { db_bind = bind, db_fvs = fvs }) + | fvs `intersectsVarSet` so_far + = extendVarSetList so_far (bindersOf bind) + | otherwise = so_far ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) @@ -2643,8 +2736,9 @@ splitDictBinds dbs bndr_set -- Important that it's foldl' not foldr; -- we're accumulating the set of dumped ids in dump_set where - split_db (free_dbs, dump_dbs, dump_idset) db@(bind, fvs) - | dump_idset `intersectsVarSet` fvs -- Dump it + split_db (free_dbs, dump_dbs, dump_idset) db + | DB { db_bind = bind, db_fvs = fvs } <- db + , dump_idset `intersectsVarSet` fvs -- Dump it = (free_dbs, dump_dbs `snocBag` db, extendVarSetList dump_idset (bindersOf bind)) ===================================== libraries/base/GHC/Exts.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Exts breakpoint, breakpointCond, -- * Ids with special behaviour - lazy, inline, oneShot, + inline, noinline, lazy, oneShot, -- * Running 'RealWorld' state thread runRW#, ===================================== rts/ProfHeap.c ===================================== @@ -1336,12 +1336,12 @@ void heapCensus (Time t) // future restriction by biography. #if defined(PROFILING) if (RtsFlags.ProfFlags.bioSelector == NULL) +#endif { freeEra(census); census->hash = NULL; census->arena = NULL; } -#endif // we're into the next time period now nextEra(); ===================================== testsuite/tests/simplCore/should_run/T17151.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE FlexibleContexts #-} +module Main where + +import T17151a + +main :: IO () +main = do + let ys :: Array P Int Int + ys = computeS (makeArray D 1 (const 5)) + applyStencil :: + (Source P ix Int, Load D ix Int) + => Stencil ix Int Int + -> Array P ix Int + -> Array P ix Int + applyStencil s = computeS . mapStencil s + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) + print (applyStencil (makeConvolutionStencilFromKernel ys) ys `unsafeIndex` 0) ===================================== testsuite/tests/simplCore/should_run/T17151.stdout ===================================== @@ -0,0 +1,2 @@ +55 +55 ===================================== testsuite/tests/simplCore/should_run/T17151a.hs ===================================== @@ -0,0 +1,205 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE EmptyDataDecls #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +module T17151a + ( computeS + , Stencil + , P(..) + , D(..) + , makeConvolutionStencilFromKernel + , mapStencil + , Array + , Construct(..) + , Source(..) + , Load(..) + , Mutable(..) + ) where + +import Control.Monad.ST +import Data.Functor.Identity +import GHC.STRef +import GHC.ST +import GHC.Exts +import Unsafe.Coerce +import Data.Kind + +---- Hacked up stuff to simulate primitive package +class Prim e where + indexByteArray :: ByteArray -> Int -> e + sizeOf :: e ->Int +instance Prim Int where + indexByteArray _ _ = 55 + sizeOf _ = 99 + +data ByteArray = BA +type MutableByteArray s = STRef s Int + +class Monad m => PrimMonad m where + type PrimState m + primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a +instance PrimMonad (ST s) where + type PrimState (ST s) = s + primitive = ST + +unsafeFreezeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> m ByteArray +unsafeFreezeByteArray a = return (unsafeCoerce a) + +newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m)) +newByteArray (I# n#) + = primitive (\s# -> case newMutVar# 33 s# of + (# s'#, arr# #) -> (# s'#, STRef arr# #)) + +writeByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> e -> m () +writeByteArray _ _ _ = return () + +----- End of hacked up stuff + +-------------- +newtype Stencil ix e a = + Stencil ((ix -> e) -> ix -> a) + +mapStencil :: Source r ix e => Stencil ix e a -> Array r ix e -> Array D ix a +mapStencil (Stencil stencilF) arr = DArray (size arr) (stencilF (unsafeIndex arr)) +{-# INLINE mapStencil #-} + +makeConvolutionStencilFromKernel + :: (Source r ix e, Num e) + => Array r ix e + -> Stencil ix e e +makeConvolutionStencilFromKernel arr = Stencil stencil + where + sz = size arr + sCenter = liftIndex (`quot` 2) sz + stencil getVal ix = + runIdentity $ + loopM 0 (< totalElem sz) (+ 1) 0 $ \i a -> + pure $ accum a (fromLinearIndex sz i) (unsafeLinearIndex arr i) + where + ixOff = liftIndex2 (+) ix sCenter + accum acc kIx kVal = getVal (liftIndex2 (-) ixOff kIx) * kVal + acc + {-# INLINE accum #-} + {-# INLINE stencil #-} +{-# INLINE makeConvolutionStencilFromKernel #-} + + +computeS :: (Mutable r ix e, Load r' ix e) => Array r' ix e -> Array r ix e +computeS arr = runST $ do + marr <- unsafeNew (size arr) + unsafeLoadIntoS marr arr + unsafeFreeze marr +{-# INLINE computeS #-} + + +data D = D deriving Show + +data instance Array D ix e = DArray{dSize :: ix, + dIndex :: ix -> e} + +instance Index ix => Construct D ix e where + makeArray _ = DArray + {-# INLINE makeArray #-} + +instance Index ix => Source D ix e where + unsafeIndex = dIndex + {-# INLINE unsafeIndex #-} + +instance Index ix => Load D ix e where + size = dSize + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +data P = P deriving Show + +data instance Array P ix e = PArray ix ByteArray + +instance (Prim e, Index ix) => Construct P ix e where + makeArray _ sz f = computeS (makeArray D sz f) + {-# INLINE makeArray #-} + +instance (Prim e, Index ix) => Source P ix e where + unsafeIndex (PArray sz a) = indexByteArray a . toLinearIndex sz + {-# INLINE unsafeIndex #-} + +instance (Prim e, Index ix) => Mutable P ix e where + data MArray s P ix e = MPArray ix (MutableByteArray s) + unsafeFreeze (MPArray sz a) = PArray sz <$> unsafeFreezeByteArray a + {-# INLINE unsafeFreeze #-} + unsafeNew sz = MPArray sz <$> newByteArray (totalElem sz * eSize) + where + eSize = sizeOf (undefined :: e) + {-# INLINE unsafeNew #-} + unsafeLinearWrite (MPArray _ ma) = writeByteArray ma + {-# INLINE unsafeLinearWrite #-} + + +instance (Prim e, Index ix) => Load P ix e where + size (PArray sz _) = sz + {-# INLINE size #-} + loadArrayM arr = splitLinearlyWith_ (totalElem (size arr)) (unsafeLinearIndex arr) + {-# INLINE loadArrayM #-} + + +unsafeLinearIndex :: Source r ix e => Array r ix e -> Int -> e +unsafeLinearIndex arr = unsafeIndex arr . fromLinearIndex (size arr) +{-# INLINE unsafeLinearIndex #-} + + +loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a +loopM init' condition increment initAcc f = go init' initAcc + where + go step acc + | condition step = f step acc >>= go (increment step) + | otherwise = return acc +{-# INLINE loopM #-} + +splitLinearlyWith_ :: + Monad m => Int -> (Int -> b) -> (Int -> b -> m ()) -> m () +splitLinearlyWith_ totalLength index write = + loopM 0 (< totalLength) (+1) () $ \i () -> write i (index i) +{-# INLINE splitLinearlyWith_ #-} + + +data family Array r ix e :: Type + +class Index ix => Construct r ix e where + makeArray :: r -> ix -> (ix -> e) -> Array r ix e + +class Load r ix e => Source r ix e where + unsafeIndex :: Array r ix e -> ix -> e + +class Index ix => Load r ix e where + size :: Array r ix e -> ix + loadArrayM :: Monad m => Array r ix e -> (Int -> e -> m ()) -> m () + unsafeLoadIntoS :: + (Mutable r' ix e, PrimMonad m) => MArray (PrimState m) r' ix e -> Array r ix e -> m () + unsafeLoadIntoS marr arr = loadArrayM arr (unsafeLinearWrite marr) + {-# INLINE unsafeLoadIntoS #-} + +class (Construct r ix e, Source r ix e) => Mutable r ix e where + data MArray s r ix e :: Type + unsafeFreeze :: PrimMonad m => MArray (PrimState m) r ix e -> m (Array r ix e) + unsafeNew :: PrimMonad m => ix -> m (MArray (PrimState m) r ix e) + unsafeLinearWrite :: PrimMonad m => MArray (PrimState m) r ix e -> Int -> e -> m () + + +class (Eq ix, Ord ix, Show ix) => + Index ix + where + totalElem :: ix -> Int + liftIndex2 :: (Int -> Int -> Int) -> ix -> ix -> ix + liftIndex :: (Int -> Int) -> ix -> ix + toLinearIndex :: ix -> ix -> Int + fromLinearIndex :: ix -> Int -> ix + +instance Index Int where + totalElem = id + toLinearIndex _ = id + fromLinearIndex _ = id + liftIndex f = f + liftIndex2 f = f ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -92,3 +92,4 @@ test('T15840', normal, compile_and_run, ['']) test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) +test('T17151', [], multimod_compile_and_run, ['T17151', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/76a1ea0374d9c83032f599fdc93543d1ddbca8e5...b305c46641f1b065e0fbc3f2cd37a89ad13ccb42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/76a1ea0374d9c83032f599fdc93543d1ddbca8e5...b305c46641f1b065e0fbc3f2cd37a89ad13ccb42 You're receiving 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 6 20:30:57 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 06 Apr 2020 16:30:57 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Fix the perf regression Message-ID: <5e8b91814f2fa_61673f8199536d9433183c3@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 1e280184 by Sebastian Graf at 2020-04-06T22:30:44+02:00 Fix the perf regression - - - - - 4 changed files: - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -27,6 +27,7 @@ import Data.List ( mapAccumL ) import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Core.Arity ( typeArity ) import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type @@ -152,7 +153,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +411,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -510,27 +511,58 @@ dmdTransform :: AnalEnv -- The strictness environment -- this function plus demand on its free variables dmdTransform env var dmd - | isDataConWorkId var -- Data constructor + -- Data constructors + | isDataConWorkId var = dmdTransformDataConSig (idArity var) (idStrictness var) dmd - + -- Dictionary component selectors | gopt Opt_DmdTxDictSel (ae_dflags env), - Just _ <- isClassOpId_maybe var -- Dictionary component selector + Just _ <- isClassOpId_maybe var = dmdTransformDictSelSig (idStrictness var) dmd - - | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + -- Imported functions + | isGlobalId var + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:import" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res - - | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing + -- Top-level or local let-bound thing for which we use LetDown ('useLetUp'). + -- In that case, we have a strictness signature to unleash in our AnalEnv. + | Just (sig, top_lvl) <- lookupSigEnv env var , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:LetDown" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl - then fn_ty -- Don't record top level things + then fn_ty -- Don't record demand on top-level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) - - | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + -- Everything else: + -- * Local let binders for which we use LetUp (cf. 'useLetUp') + -- * Lambda binders + -- * Case and constructor field binders + | let sig = mkConservativeSig env (idType var) + , let res = dmdTransformSig sig dmd + = -- pprTrace "dmdTransform:Other" (vcat [ppr var, ppr sig, ppr dmd, ppr res]) $ + addVarDmd res var (mkOnceUsedDmd dmd) + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig env (idType var) + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> Type -> StrictSig +mkConservativeSig env ty + | no_change = topSig -- no point in retaining cleared_sig when it's just Top + | otherwise = cleared_sig + where + fam_envs = ae_fam_envs env + -- This is isomorphic to topSig. But this one has the right number of + -- arguments and will possibly have conDiv after the call to + -- tryClearPreciseException! + pessimistic_sig = StrictSig $ DmdType emptyVarEnv args topDiv + args = replicate (length (typeArity ty)) topDmd + -- In contrast to pessimistic_sig, cleared_sig might not have conDiv + -- Divergence! + cleared_sig = tryClearPreciseException fam_envs ty pessimistic_sig + sig_div = snd . splitStrictSig + no_change = sig_div cleared_sig == topDiv {- ************************************************************************ @@ -603,7 +635,7 @@ dmdFix top_lvl env let_dmd orig_pairs zapIdStrictness :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdStrictness pairs - = [(setIdStrictnessClearExn env id (emptySig topDiv), rhs) | (id, rhs) <- pairs ] + = [(setIdStrictnessClearExn env id topSig, rhs) | (id, rhs) <- pairs ] {- Note [Safe abortion in the fixed-point iteration] @@ -658,7 +690,7 @@ dmdAnalRhsLetDown rec_flag env let_dmd id rhs = mkRhsDmd env rhs_arity rhs (DmdType rhs_fv rhs_dmds rhs_div, rhs') = dmdAnal env rhs_dmd rhs - sig = mkStrictSigForArity rhs_arity (mkDmdType sig_fv rhs_dmds rhs_div) + sig = mkStrictSigForArity rhs_arity (DmdType sig_fv rhs_dmds rhs_div) id' = -- pprTraceWith "dmdAnalRhsLetDown" (\sig'-> ppr id <+> ppr sig <+> ppr sig') $ setIdStrictnessClearExn env id sig -- See Note [NOINLINE and strictness] @@ -944,9 +976,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -23,8 +23,7 @@ module GHC.Types.Demand ( DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType, BothDmdArg, mkBothDmdArg, toBothDmdArg, - emptyDmdType, botDmdType, mkDmdType, addDemand, - mayThrowPreciseDmdType, + emptyDmdType, botDmdType, addDemand, mayThrowPreciseDmdType, DmdEnv, emptyDmdEnv, peelFV, findIdDemand, @@ -33,7 +32,7 @@ module GHC.Types.Demand ( topDiv, botDiv, exnDiv, conDiv, appIsDeadEnd, isDeadEndSig, pprIfaceStrictSig, StrictSig(..), mkStrictSigForArity, mkClosedStrictSig, - emptySig, botSig, cprProdSig, + emptySig, topSig, botSig, cprProdSig, isTopSig, hasDemandEnvSig, splitStrictSig, strictSigDmdEnv, prependArgsStrictSig, etaConvertStrictSig, @@ -1275,6 +1274,9 @@ emptyDmdType div = DmdType emptyDmdEnv [] div botDmdType :: DmdType botDmdType = emptyDmdType botDiv +topDmdType :: DmdType +topDmdType = emptyDmdType topDiv + isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env @@ -1284,9 +1286,6 @@ mayThrowPreciseDmdType (DmdType _ _ Dunno) = True mayThrowPreciseDmdType (DmdType _ _ ExnOrDiv) = True mayThrowPreciseDmdType _ = False -mkDmdType :: DmdEnv -> [Demand] -> Divergence -> DmdType -mkDmdType fv ds res = DmdType fv ds res - dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1788,6 +1787,9 @@ emptySig div = StrictSig (emptyDmdType div) botSig :: StrictSig botSig = StrictSig botDmdType +topSig :: StrictSig +topSig = StrictSig topDmdType + cprProdSig :: Arity -> StrictSig cprProdSig _arity = emptySig conDiv -- constructor applications never throw precise exceptions ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -658,7 +658,7 @@ setIdCprInfo :: Id -> CprSig -> Id setIdCprInfo id sig = modifyIdInfo (\info -> setCprInfo info sig) id zapIdStrictness :: Id -> Id -zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` emptySig topDiv) id +zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id -- | This predicate says whether the 'Id' has a strict demand placed on it or -- has a type such that it can always be evaluated strictly (i.e an ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -324,7 +324,7 @@ vanillaIdInfo inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, - strictnessInfo = emptySig topDiv, + strictnessInfo = topSig, cprInfo = topCprSig, callArityInfo = unknownArity, levityInfo = NoLevityInfo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e2801840896b54ab307a2ffe6b67cae2a400fe3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e2801840896b54ab307a2ffe6b67cae2a400fe3 You're receiving 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 6 20:45:23 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 06 Apr 2020 16:45:23 -0400 Subject: [Git][ghc/ghc][wip/haddock-accum] Comments / rename Message-ID: <5e8b94e3533bc_616713503ee03324985@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/haddock-accum at Glasgow Haskell Compiler / GHC Commits: c9d02d95 by Vladislav Zavialov at 2020-04-06T23:45:08+03:00 Comments / rename - - - - - 1 changed file: - compiler/parser/HaddockUtils.hs Changes: ===================================== compiler/parser/HaddockUtils.hs ===================================== @@ -253,12 +253,12 @@ instance HasHaddock (Located HsModule) where HdkA (getBufSpan l_name) $ do docs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l_name))) $ - takeHdkComments getDocNext + takeHdkComments mkDocNext pure $ concatLHsDocString docs hsmodExports' <- traverse @Maybe addHaddock (hsmodExports mod) traverse_ registerHdkA (hsmodImports mod) let layout_info = hsmodLayout mod - hsmodDecls' <- addHaddockInterleaveItems layout_info (getDocDecl layout_info) (hsmodDecls mod) + hsmodDecls' <- addHaddockInterleaveItems layout_info (mkDocHsDecl layout_info) (hsmodDecls mod) pure $ L l_mod $ mod { hsmodExports = hsmodExports' , hsmodDecls = hsmodDecls' @@ -267,15 +267,62 @@ instance HasHaddock (Located HsModule) where instance HasHaddock (Located [LIE GhcPs]) where addHaddock (L l_exports exports) = delimitHdkA l_exports $ do - exports' <- addHaddockInterleaveItems NoLayoutInfo getDocIE exports + exports' <- addHaddockInterleaveItems NoLayoutInfo mkDocIE exports registerHdkA (L (srcLocSpan (srcSpanEnd l_exports)) ()) -- Do not conume comments after the closing parenthesis pure $ L l_exports exports' instance HasHaddock (LIE GhcPs) where addHaddock a = a <$ registerHdkA a --- Add Haddock items to a list of non-Haddock items. --- Used to process export lists (with getDocIE) and declarations (with getDocDecl). +{- Add Haddock items to a list of non-Haddock items. +Used to process export lists (with mkDocIE) and declarations (with mkDocHsDecl). + +For example: + + module M where + -- | Comment on D + data D = MkD -- ^ Comment on MkD + data C = MkC -- ^ Comment on MkC + -- ^ Comment on C + +In this case, we should produce four HsDecl items (pseudo-code): + + 1. DocD (DocCommentNext "Comment on D") + 2. TyClD (DataDecl "D" ... [ConDeclH98 "MkD" ... (Just "Comment on MkD")]) + 3. TyClD (DataDecl "C" ... [ConDeclH98 "MkC" ... (Just "Comment on MkC")]) + 4. DocD (DocCommentPrev "Comment on C") + +The inputs to addHaddockInterleaveItems are: + + * layout_info :: LayoutInfo + + In the example above, note that the indentation level inside the module is + 2 spaces. It would be represented as layout_info = VirtualBraces 2. + + It is used to delimit the search space for comments when processing + declarations. Here, we restrict indentation levels to >=(2+1), so that when + we look up comment on MkC, we get "Comment on MkC" but not "Comment on C". + + * get_doc_item :: PsLocated HdkComment -> Maybe a + + This is the function used to look up documentation comments. + In the above example, get_doc_item = mkDocHsDecl layout_info, + and it will produce the following parts of the output: + + DocD (DocCommentNext "Comment on D") + DocD (DocCommentPrev "Comment on C") + + * The list of items. These are the declarations that will be annotated with + documentation comments. + + Before processing: + TyClD (DataDecl "D" ... [ConDeclH98 "MkD" ... Nothing]) + TyClD (DataDecl "C" ... [ConDeclH98 "MkC" ... Nothing]) + + After processing: + TyClD (DataDecl "D" ... [ConDeclH98 "MkD" ... (Just "Comment on MkD")]) + TyClD (DataDecl "C" ... [ConDeclH98 "MkC" ... (Just "Comment on MkC")]) +-} addHaddockInterleaveItems :: forall a. HasHaddock a @@ -302,11 +349,11 @@ addHaddockInterleaveItems layout_info get_doc_item = go let loc_range = LocRange mempty mempty (ColumnFrom (n+1)) in HdkA l (inLocRange loc_range m) -getDocDecl :: LayoutInfo -> PsLocated HdkComment -> Maybe (LHsDecl GhcPs) -getDocDecl layout_info a = mapLoc (DocD noExtField) <$> getDocDecl' layout_info a +mkDocHsDecl :: LayoutInfo -> PsLocated HdkComment -> Maybe (LHsDecl GhcPs) +mkDocHsDecl layout_info a = mapLoc (DocD noExtField) <$> mkDocDecl layout_info a -getDocDecl' :: LayoutInfo -> PsLocated HdkComment -> Maybe LDocDecl -getDocDecl' layout_info (L l_comment hdk_comment) +mkDocDecl :: LayoutInfo -> PsLocated HdkComment -> Maybe LDocDecl +mkDocDecl layout_info (L l_comment hdk_comment) | indent_mismatch = Nothing | otherwise = Just $ L (mkSrcSpanPs l_comment) $ @@ -321,8 +368,8 @@ getDocDecl' layout_info (L l_comment hdk_comment) ExplicitBraces -> False VirtualBraces n -> n /= srcSpanStartCol (psRealSpan l_comment) -getDocIE :: PsLocated HdkComment -> Maybe (LIE GhcPs) -getDocIE (L l_comment hdk_comment) = +mkDocIE :: PsLocated HdkComment -> Maybe (LIE GhcPs) +mkDocIE (L l_comment hdk_comment) = case hdk_comment of HdkCommentSection n doc -> Just $ L l (IEGroup noExtField n doc) HdkCommentNamed s _doc -> Just $ L l (IEDocNamed noExtField s) @@ -330,13 +377,13 @@ getDocIE (L l_comment hdk_comment) = _ -> Nothing where l = mkSrcSpanPs l_comment -getDocNext :: PsLocated HdkComment -> Maybe LHsDocString -getDocNext (L l (HdkCommentNext doc)) = Just $ L (mkSrcSpanPs l) doc -getDocNext _ = Nothing +mkDocNext :: PsLocated HdkComment -> Maybe LHsDocString +mkDocNext (L l (HdkCommentNext doc)) = Just $ L (mkSrcSpanPs l) doc +mkDocNext _ = Nothing -getDocPrev :: PsLocated HdkComment -> Maybe LHsDocString -getDocPrev (L l (HdkCommentPrev doc)) = Just $ L (mkSrcSpanPs l) doc -getDocPrev _ = Nothing +mkDocPrev :: PsLocated HdkComment -> Maybe LHsDocString +mkDocPrev (L l (HdkCommentPrev doc)) = Just $ L (mkSrcSpanPs l) doc +mkDocPrev _ = Nothing instance HasHaddock (LHsDecl GhcPs) where addHaddock ldecl = @@ -391,7 +438,7 @@ instance HasHaddock (HsDecl GhcPs) where = do registerHdkA tcdLName where_cls' <- - addHaddockInterleaveItems tcdLayout (getDocDecl tcdLayout) $ + addHaddockInterleaveItems tcdLayout (mkDocHsDecl tcdLayout) $ flattenBindsAndSigs (tcdMeths, tcdSigs, tcdATs, tcdATDefs, [], []) pure $ let (tcdMeths', tcdSigs', tcdATs', tcdATDefs', _, tcdDocs) = partitionBindsAndSigs id where_cls' @@ -481,22 +528,22 @@ instance HasHaddock (LConDecl GhcPs) where trailingConDocs <- do nextDocs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l_con))) $ - peekHdkComments getDocNext + peekHdkComments mkDocNext -- See Note [Trailing comment on constructor declaration] let inner_docs_range = locRangeFrom (getBufPos (srcSpanStart l_con)) <> locRangeTo (getBufPos (srcSpanEnd l_con)) innerDocs <- inLocRange inner_docs_range (peekHdkComments Just) if null innerDocs && null nextDocs then inLocRange (locRangeFrom (getBufPos (srcSpanEnd l_con))) $ - takeHdkComments getDocPrev + takeHdkComments mkDocPrev else return [] let getConDoc (L l _) = HdkA (getBufSpan l) $ do nextDocs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l))) $ - takeHdkComments getDocNext + takeHdkComments mkDocNext prevDocs <- inLocRange (locRangeFrom (getBufPos (srcSpanEnd l))) $ - takeHdkComments getDocPrev + takeHdkComments mkDocPrev return $ concatLHsDocString (nextDocs ++ prevDocs ++ trailingConDocs) hdk_a_m (HdkA _ m) = m hdk_a_m $ case con of @@ -566,10 +613,10 @@ instance HasHaddock (LConDeclField GhcPs) where HdkA (getBufSpan l_fld) $ do nextDocs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l_fld))) $ - takeHdkComments getDocNext + takeHdkComments mkDocNext prevDocs <- inLocRange (locRangeFrom (getBufPos (srcSpanEnd l_fld))) $ - takeHdkComments getDocPrev + takeHdkComments mkDocPrev let cd_fld_doc = concatLHsDocString (nextDocs ++ prevDocs) return $ L l_fld $ case fld of ConDeclField { cd_fld_ext, cd_fld_names, cd_fld_type } -> @@ -616,13 +663,31 @@ instance HasHaddock (LHsType GhcPs) where (l_start, l_end) = (srcSpanStart l, srcSpanEnd l) before_t = locRangeTo (getBufPos l_start) after_t = locRangeFrom (getBufPos l_end) - nextDocs <- inLocRange before_t $ takeHdkComments getDocNext - prevDocs <- inLocRange after_t $ takeHdkComments getDocPrev + nextDocs <- inLocRange before_t $ takeHdkComments mkDocNext + prevDocs <- inLocRange after_t $ takeHdkComments mkDocPrev let mDoc = concatLHsDocString (nextDocs ++ prevDocs) return $ case mDoc of Nothing -> t Just doc -> HsDocTy noExtField ltype doc +-- | Represents a predicate on BufPos: +-- +-- LowerLocBound | BufPos -> Bool +-- --------------+----------------- +-- StartOfFile | const True +-- StartLoc p | (>= p) +-- +-- The semigroup instance corresponds to (&&). +-- +-- We don't use the BufPos -> Bool representation +-- as it would lead to redundant checks. +-- +-- That is, instead of +-- +-- (pos >= 20) && (pos >= 30) && (pos >= 40) +-- +-- We'd rather only do the (>=40) check. So we reify the predicate to make +-- sure we only check for the most restrictive bound. data LowerLocBound = StartOfFile | StartLoc BufPos instance Semigroup LowerLocBound where @@ -633,6 +698,24 @@ instance Semigroup LowerLocBound where instance Monoid LowerLocBound where mempty = StartOfFile +-- | Represents a predicate on BufPos: +-- +-- UpperLocBound | BufPos -> Bool +-- --------------+----------------- +-- EndOfFile | const True +-- EndLoc p | (<= p) +-- +-- The semigroup instance corresponds to (&&). +-- +-- We don't use the BufPos -> Bool representation +-- as it would lead to redundant checks. +-- +-- That is, instead of +-- +-- (pos <= 40) && (pos <= 30) && (pos <= 20) +-- +-- We'd rather only do the (<=20) check. So we reify the predicate to make +-- sure we only check for the most restrictive bound. data UpperLocBound = EndOfFile | EndLoc BufPos instance Semigroup UpperLocBound where @@ -643,6 +726,14 @@ instance Semigroup UpperLocBound where instance Monoid UpperLocBound where mempty = EndOfFile +-- | Represents a predicate on the column number. +-- +-- ColumnBound | Int -> Bool +-- --------------+----------------- +-- ColumnFrom n | (>=n) +-- +-- The semigroup instance corresponds to (&&). +-- newtype ColumnBound = ColumnFrom Int -- n >= 1 instance Semigroup ColumnBound where @@ -654,9 +745,9 @@ instance Monoid ColumnBound where -- | A location range for extracting documentation comments. data LocRange = LocRange - LowerLocBound -- from - UpperLocBound -- to - ColumnBound + { loc_range_from :: LowerLocBound, + loc_range_to :: UpperLocBound, + loc_range_col :: ColumnBound } instance Semigroup LocRange where LocRange from1 to1 col1 <> LocRange from2 to2 col2 = @@ -666,11 +757,11 @@ instance Monoid LocRange where mempty = LocRange mempty mempty mempty locRangeFrom :: Maybe BufPos -> LocRange -locRangeFrom (Just l) = LocRange (StartLoc l) EndOfFile mempty +locRangeFrom (Just l) = mempty { loc_range_from = StartLoc l } locRangeFrom Nothing = mempty locRangeTo :: Maybe BufPos -> LocRange -locRangeTo (Just l) = LocRange StartOfFile (EndLoc l) mempty +locRangeTo (Just l) = mempty { loc_range_to = EndLoc l } locRangeTo Nothing = mempty inLocRange :: LocRange -> HdkM a -> HdkM a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9d02d95e096febfb723b7a10b26386a47b75331 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9d02d95e096febfb723b7a10b26386a47b75331 You're receiving 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 6 23:22:07 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 06 Apr 2020 19:22:07 -0400 Subject: [Git][ghc/ghc][wip/haddock-accum] Comments / rename Message-ID: <5e8bb99f77be5_61673f8198ee100c33539a@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/haddock-accum at Glasgow Haskell Compiler / GHC Commits: 5ddbd585 by Vladislav Zavialov at 2020-04-07T02:21:52+03:00 Comments / rename - - - - - 1 changed file: - compiler/parser/HaddockUtils.hs Changes: ===================================== compiler/parser/HaddockUtils.hs ===================================== @@ -253,12 +253,12 @@ instance HasHaddock (Located HsModule) where HdkA (getBufSpan l_name) $ do docs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l_name))) $ - takeHdkComments getDocNext + takeHdkComments mkDocNext pure $ concatLHsDocString docs hsmodExports' <- traverse @Maybe addHaddock (hsmodExports mod) traverse_ registerHdkA (hsmodImports mod) let layout_info = hsmodLayout mod - hsmodDecls' <- addHaddockInterleaveItems layout_info (getDocDecl layout_info) (hsmodDecls mod) + hsmodDecls' <- addHaddockInterleaveItems layout_info (mkDocHsDecl layout_info) (hsmodDecls mod) pure $ L l_mod $ mod { hsmodExports = hsmodExports' , hsmodDecls = hsmodDecls' @@ -267,15 +267,62 @@ instance HasHaddock (Located HsModule) where instance HasHaddock (Located [LIE GhcPs]) where addHaddock (L l_exports exports) = delimitHdkA l_exports $ do - exports' <- addHaddockInterleaveItems NoLayoutInfo getDocIE exports + exports' <- addHaddockInterleaveItems NoLayoutInfo mkDocIE exports registerHdkA (L (srcLocSpan (srcSpanEnd l_exports)) ()) -- Do not conume comments after the closing parenthesis pure $ L l_exports exports' instance HasHaddock (LIE GhcPs) where addHaddock a = a <$ registerHdkA a --- Add Haddock items to a list of non-Haddock items. --- Used to process export lists (with getDocIE) and declarations (with getDocDecl). +{- Add Haddock items to a list of non-Haddock items. +Used to process export lists (with mkDocIE) and declarations (with mkDocHsDecl). + +For example: + + module M where + -- | Comment on D + data D = MkD -- ^ Comment on MkD + data C = MkC -- ^ Comment on MkC + -- ^ Comment on C + +In this case, we should produce four HsDecl items (pseudo-code): + + 1. DocD (DocCommentNext "Comment on D") + 2. TyClD (DataDecl "D" ... [ConDeclH98 "MkD" ... (Just "Comment on MkD")]) + 3. TyClD (DataDecl "C" ... [ConDeclH98 "MkC" ... (Just "Comment on MkC")]) + 4. DocD (DocCommentPrev "Comment on C") + +The inputs to addHaddockInterleaveItems are: + + * layout_info :: LayoutInfo + + In the example above, note that the indentation level inside the module is + 2 spaces. It would be represented as layout_info = VirtualBraces 2. + + It is used to delimit the search space for comments when processing + declarations. Here, we restrict indentation levels to >=(2+1), so that when + we look up comment on MkC, we get "Comment on MkC" but not "Comment on C". + + * get_doc_item :: PsLocated HdkComment -> Maybe a + + This is the function used to look up documentation comments. + In the above example, get_doc_item = mkDocHsDecl layout_info, + and it will produce the following parts of the output: + + DocD (DocCommentNext "Comment on D") + DocD (DocCommentPrev "Comment on C") + + * The list of items. These are the declarations that will be annotated with + documentation comments. + + Before processing: + TyClD (DataDecl "D" ... [ConDeclH98 "MkD" ... Nothing]) + TyClD (DataDecl "C" ... [ConDeclH98 "MkC" ... Nothing]) + + After processing: + TyClD (DataDecl "D" ... [ConDeclH98 "MkD" ... (Just "Comment on MkD")]) + TyClD (DataDecl "C" ... [ConDeclH98 "MkC" ... (Just "Comment on MkC")]) +-} addHaddockInterleaveItems :: forall a. HasHaddock a @@ -299,14 +346,14 @@ addHaddockInterleaveItems layout_info get_doc_item = go ExplicitBraces -> id VirtualBraces n -> \(HdkA l m) -> - let loc_range = LocRange mempty mempty (ColumnFrom (n+1)) + let loc_range = mempty { loc_range_col = ColumnFrom (n+1) } in HdkA l (inLocRange loc_range m) -getDocDecl :: LayoutInfo -> PsLocated HdkComment -> Maybe (LHsDecl GhcPs) -getDocDecl layout_info a = mapLoc (DocD noExtField) <$> getDocDecl' layout_info a +mkDocHsDecl :: LayoutInfo -> PsLocated HdkComment -> Maybe (LHsDecl GhcPs) +mkDocHsDecl layout_info a = mapLoc (DocD noExtField) <$> mkDocDecl layout_info a -getDocDecl' :: LayoutInfo -> PsLocated HdkComment -> Maybe LDocDecl -getDocDecl' layout_info (L l_comment hdk_comment) +mkDocDecl :: LayoutInfo -> PsLocated HdkComment -> Maybe LDocDecl +mkDocDecl layout_info (L l_comment hdk_comment) | indent_mismatch = Nothing | otherwise = Just $ L (mkSrcSpanPs l_comment) $ @@ -321,8 +368,8 @@ getDocDecl' layout_info (L l_comment hdk_comment) ExplicitBraces -> False VirtualBraces n -> n /= srcSpanStartCol (psRealSpan l_comment) -getDocIE :: PsLocated HdkComment -> Maybe (LIE GhcPs) -getDocIE (L l_comment hdk_comment) = +mkDocIE :: PsLocated HdkComment -> Maybe (LIE GhcPs) +mkDocIE (L l_comment hdk_comment) = case hdk_comment of HdkCommentSection n doc -> Just $ L l (IEGroup noExtField n doc) HdkCommentNamed s _doc -> Just $ L l (IEDocNamed noExtField s) @@ -330,13 +377,13 @@ getDocIE (L l_comment hdk_comment) = _ -> Nothing where l = mkSrcSpanPs l_comment -getDocNext :: PsLocated HdkComment -> Maybe LHsDocString -getDocNext (L l (HdkCommentNext doc)) = Just $ L (mkSrcSpanPs l) doc -getDocNext _ = Nothing +mkDocNext :: PsLocated HdkComment -> Maybe LHsDocString +mkDocNext (L l (HdkCommentNext doc)) = Just $ L (mkSrcSpanPs l) doc +mkDocNext _ = Nothing -getDocPrev :: PsLocated HdkComment -> Maybe LHsDocString -getDocPrev (L l (HdkCommentPrev doc)) = Just $ L (mkSrcSpanPs l) doc -getDocPrev _ = Nothing +mkDocPrev :: PsLocated HdkComment -> Maybe LHsDocString +mkDocPrev (L l (HdkCommentPrev doc)) = Just $ L (mkSrcSpanPs l) doc +mkDocPrev _ = Nothing instance HasHaddock (LHsDecl GhcPs) where addHaddock ldecl = @@ -391,7 +438,7 @@ instance HasHaddock (HsDecl GhcPs) where = do registerHdkA tcdLName where_cls' <- - addHaddockInterleaveItems tcdLayout (getDocDecl tcdLayout) $ + addHaddockInterleaveItems tcdLayout (mkDocHsDecl tcdLayout) $ flattenBindsAndSigs (tcdMeths, tcdSigs, tcdATs, tcdATDefs, [], []) pure $ let (tcdMeths', tcdSigs', tcdATs', tcdATDefs', _, tcdDocs) = partitionBindsAndSigs id where_cls' @@ -481,22 +528,22 @@ instance HasHaddock (LConDecl GhcPs) where trailingConDocs <- do nextDocs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l_con))) $ - peekHdkComments getDocNext + peekHdkComments mkDocNext -- See Note [Trailing comment on constructor declaration] let inner_docs_range = locRangeFrom (getBufPos (srcSpanStart l_con)) <> locRangeTo (getBufPos (srcSpanEnd l_con)) innerDocs <- inLocRange inner_docs_range (peekHdkComments Just) if null innerDocs && null nextDocs then inLocRange (locRangeFrom (getBufPos (srcSpanEnd l_con))) $ - takeHdkComments getDocPrev + takeHdkComments mkDocPrev else return [] let getConDoc (L l _) = HdkA (getBufSpan l) $ do nextDocs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l))) $ - takeHdkComments getDocNext + takeHdkComments mkDocNext prevDocs <- inLocRange (locRangeFrom (getBufPos (srcSpanEnd l))) $ - takeHdkComments getDocPrev + takeHdkComments mkDocPrev return $ concatLHsDocString (nextDocs ++ prevDocs ++ trailingConDocs) hdk_a_m (HdkA _ m) = m hdk_a_m $ case con of @@ -566,10 +613,10 @@ instance HasHaddock (LConDeclField GhcPs) where HdkA (getBufSpan l_fld) $ do nextDocs <- inLocRange (locRangeTo (getBufPos (srcSpanStart l_fld))) $ - takeHdkComments getDocNext + takeHdkComments mkDocNext prevDocs <- inLocRange (locRangeFrom (getBufPos (srcSpanEnd l_fld))) $ - takeHdkComments getDocPrev + takeHdkComments mkDocPrev let cd_fld_doc = concatLHsDocString (nextDocs ++ prevDocs) return $ L l_fld $ case fld of ConDeclField { cd_fld_ext, cd_fld_names, cd_fld_type } -> @@ -616,13 +663,31 @@ instance HasHaddock (LHsType GhcPs) where (l_start, l_end) = (srcSpanStart l, srcSpanEnd l) before_t = locRangeTo (getBufPos l_start) after_t = locRangeFrom (getBufPos l_end) - nextDocs <- inLocRange before_t $ takeHdkComments getDocNext - prevDocs <- inLocRange after_t $ takeHdkComments getDocPrev + nextDocs <- inLocRange before_t $ takeHdkComments mkDocNext + prevDocs <- inLocRange after_t $ takeHdkComments mkDocPrev let mDoc = concatLHsDocString (nextDocs ++ prevDocs) return $ case mDoc of Nothing -> t Just doc -> HsDocTy noExtField ltype doc +-- | Represents a predicate on BufPos: +-- +-- LowerLocBound | BufPos -> Bool +-- --------------+----------------- +-- StartOfFile | const True +-- StartLoc p | (>= p) +-- +-- The semigroup instance corresponds to (&&). +-- +-- We don't use the BufPos -> Bool representation +-- as it would lead to redundant checks. +-- +-- That is, instead of +-- +-- (pos >= 20) && (pos >= 30) && (pos >= 40) +-- +-- We'd rather only do the (>=40) check. So we reify the predicate to make +-- sure we only check for the most restrictive bound. data LowerLocBound = StartOfFile | StartLoc BufPos instance Semigroup LowerLocBound where @@ -633,6 +698,24 @@ instance Semigroup LowerLocBound where instance Monoid LowerLocBound where mempty = StartOfFile +-- | Represents a predicate on BufPos: +-- +-- UpperLocBound | BufPos -> Bool +-- --------------+----------------- +-- EndOfFile | const True +-- EndLoc p | (<= p) +-- +-- The semigroup instance corresponds to (&&). +-- +-- We don't use the BufPos -> Bool representation +-- as it would lead to redundant checks. +-- +-- That is, instead of +-- +-- (pos <= 40) && (pos <= 30) && (pos <= 20) +-- +-- We'd rather only do the (<=20) check. So we reify the predicate to make +-- sure we only check for the most restrictive bound. data UpperLocBound = EndOfFile | EndLoc BufPos instance Semigroup UpperLocBound where @@ -643,6 +726,14 @@ instance Semigroup UpperLocBound where instance Monoid UpperLocBound where mempty = EndOfFile +-- | Represents a predicate on the column number. +-- +-- ColumnBound | Int -> Bool +-- --------------+----------------- +-- ColumnFrom n | (>=n) +-- +-- The semigroup instance corresponds to (&&). +-- newtype ColumnBound = ColumnFrom Int -- n >= 1 instance Semigroup ColumnBound where @@ -654,9 +745,9 @@ instance Monoid ColumnBound where -- | A location range for extracting documentation comments. data LocRange = LocRange - LowerLocBound -- from - UpperLocBound -- to - ColumnBound + { loc_range_from :: LowerLocBound, + loc_range_to :: UpperLocBound, + loc_range_col :: ColumnBound } instance Semigroup LocRange where LocRange from1 to1 col1 <> LocRange from2 to2 col2 = @@ -666,11 +757,11 @@ instance Monoid LocRange where mempty = LocRange mempty mempty mempty locRangeFrom :: Maybe BufPos -> LocRange -locRangeFrom (Just l) = LocRange (StartLoc l) EndOfFile mempty +locRangeFrom (Just l) = mempty { loc_range_from = StartLoc l } locRangeFrom Nothing = mempty locRangeTo :: Maybe BufPos -> LocRange -locRangeTo (Just l) = LocRange StartOfFile (EndLoc l) mempty +locRangeTo (Just l) = mempty { loc_range_to = EndLoc l } locRangeTo Nothing = mempty inLocRange :: LocRange -> HdkM a -> HdkM a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ddbd5856f4293ab7368ce1128b10296611fa7c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ddbd5856f4293ab7368ce1128b10296611fa7c5 You're receiving 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 7 00:30:57 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 06 Apr 2020 20:30:57 -0400 Subject: [Git][ghc/ghc][wip/T15304] simplifier: Kill off ufKeenessFactor Message-ID: <5e8bc9c1683b4_61677c82e0c3362138@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T15304 at Glasgow Haskell Compiler / GHC Commits: efe4a440 by Ben Gamari at 2020-04-06T20:30:40-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 11 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/plugins/all.T - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1002,10 +1002,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1024,6 +1020,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1307,8 +1319,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1553,14 +1564,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1569,8 +1575,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3023,8 +3021,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,80 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/plugins/all.T ===================================== @@ -167,7 +167,6 @@ test('plugin-recomp-flags', test('plugin-recomp-change', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}') ], makefile_test, []) @@ -175,7 +174,6 @@ test('plugin-recomp-change', test('plugin-recomp-change-prof', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}'), when(not config.have_profiling,skip) ], ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -1,4 +1,5 @@ RULES: "SPEC $cm @()" [0] RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] +"SPEC/T17966 $fShowMaybe_$cshow @Integer" "SPEC/T17966 $fShowMaybe_$cshowList @Integer" "SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/efe4a44052c3bde764d177e4bd0cff022fa9a00e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/efe4a44052c3bde764d177e4bd0cff022fa9a00e You're receiving 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 7 06:00:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 07 Apr 2020 02:00:15 -0400 Subject: [Git][ghc/ghc][master] rts: ProfHeap: Fix memory leak when not compiled with profiling Message-ID: <5e8c16ef59a5c_61673f81bb9e8b0433795f2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - 1 changed file: - rts/ProfHeap.c Changes: ===================================== rts/ProfHeap.c ===================================== @@ -1336,12 +1336,12 @@ void heapCensus (Time t) // future restriction by biography. #if defined(PROFILING) if (RtsFlags.ProfFlags.bioSelector == NULL) +#endif { freeEra(census); census->hash = NULL; census->arena = NULL; } -#endif // we're into the next time period now nextEra(); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f38e8d61f066c3064c600c352eebcd87f28d989a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f38e8d61f066c3064c600c352eebcd87f28d989a You're receiving 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 7 06:00:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 07 Apr 2020 02:00:50 -0400 Subject: [Git][ghc/ghc][master] Re-export GHC.Magic.noinline from base Message-ID: <5e8c17125bd7c_61673f81bb9e8b043382432@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 1 changed file: - libraries/base/GHC/Exts.hs Changes: ===================================== libraries/base/GHC/Exts.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Exts breakpoint, breakpointCond, -- * Ids with special behaviour - lazy, inline, oneShot, + inline, noinline, lazy, oneShot, -- * Running 'RealWorld' state thread runRW#, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcd668593e1c9e00c5d9c72960b4833dd526cb9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcd668593e1c9e00c5d9c72960b4833dd526cb9a You're receiving 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 7 06:04:21 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 07 Apr 2020 02:04:21 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 6 commits: Don't override proc CafInfos in ticky builds Message-ID: <5e8c17e5cd0db_61673f81bb9e8b0433826ef@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 9a32ab1a by Ömer Sinan Ağacan at 2020-04-07T02:04:18-04:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - compiler/main/UpdateCafInfos.hs → compiler/main/UpdateIdInfos.hs - libraries/base/GHC/Exts.hs - rts/ProfHeap.c - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0fd786cb5bb8e4e4801e4a570ca23546ebc6ca7...9a32ab1abbe3eb1b6f6e9f83bbf928ee04d316f9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0fd786cb5bb8e4e4801e4a570ca23546ebc6ca7...9a32ab1abbe3eb1b6f6e9f83bbf928ee04d316f9 You're receiving 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 7 08:28:55 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 07 Apr 2020 04:28:55 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5e8c39c7b84c3_616713503ee034075e6@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: d8a84cbc by Andreas Klebinger at 2020-04-07T10:28:42+02:00 Refactor linear reg alloc to remember past assignments. We used to pick the first free register, which is damn fast but produces fixup blocks on the regular. Now we look for past assignments first. This means for loops with blocks A, B, C if a variable is live in A & C we will pick the right register (if available) in C. This avoids some needless fixup blocks. - - - - - 11 changed files: - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs - compiler/GHC/CmmToAsm/Reg/Linear/State.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs - compiler/utils/Outputable.hs Changes: ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -639,17 +639,19 @@ sequenceChain _info _weights [x] = [x] sequenceChain info weights' blocks@((BasicBlock entry _):_) = let weights :: CFG weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' + -- cfg' + weights' where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights + -- TODO: Remove + -- (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' + -- cfg' = {-# SCC rewriteEdges #-} + -- mapFoldlWithKey + -- (\cfg from m -> + -- mapFoldlWithKey + -- (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + -- cfg m ) + -- weights' + -- globalEdgeWeights directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,20 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG weights proc@(CmmProc _info _lab _live graph) cfg = + staticPredCfg (g_entry graph) . optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +758,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +946,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,12 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +252,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +287,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +331,20 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + assig <- getBlockAssigR + + -- pprTraceM "assignment" $ ppr assig (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +380,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +407,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are love on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> BlockId -- ^ the id of the current block, for debugging @@ -476,7 +487,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,7 +497,9 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform + block_assig <- getBlockAssigR case regUsageOfInstr platform instr of { RU read written -> do let real_written = [ rr | (RegReal rr) <- written ] @@ -525,10 +538,12 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. - -- when (not $ null fixup_blocks) $ - -- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) +-- when (not $ null fixup_blocks) $ +-- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) -- (e) Delete all register assignments for temps which are read -- (only) and die here. Update the free register list. @@ -737,7 +752,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +764,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +795,15 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +findVirtRegAny :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe Loc) +findVirtRegAny vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe Loc -> Maybe Loc + findVirtRegAssig assig z = + lookupUFM (snd assig) vreg <|> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,13 +820,20 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] case freeRegs_thisClass of -- case (2): we have a free register (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + do _r <- findVirtRegAny r + -- pprTraceM "free" $ ppr (_r, my_reg, freeRegs_thisClass) + my_reg <- return $ case _r of + Just (InReg my_reg') + | my_reg' `elem` freeRegs_thisClass -> my_reg' + _ -> my_reg :: RealReg + -- pprTraceM "findVirtRegAny" $ ppr (my_reg, _r) + spills' <- loadTemp r spill_loc my_reg spills setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) setFreeRegsR $ frAllocateReg platform my_reg freeRegs ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -138,6 +138,9 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + -- | Map virtual regs to regs they have been assigned in the past. + , ra_sugg_assig :: RegMap Loc } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} @@ -52,7 +53,9 @@ import GHC.Cmm.BlockId import GHC.Platform import GHC.Types.Unique import GHC.Types.Unique.Supply +import GHC.Types.Unique.FM +import Control.Applicative import Control.Monad (ap) -- Avoids using unboxed tuples when loading into GHCi @@ -111,7 +114,8 @@ runR config block_assig freeregs assig stack us thing = , ra_us = us , ra_spills = [] , ra_config = config - , ra_fixups = [] }) + , ra_fixups = [] + , ra_sugg_assig = assig }) of RA_Result state returned_thing -> (ra_blockassig state, ra_stack state, makeRAStats state, returned_thing) @@ -157,6 +161,24 @@ setAssigR :: RegMap Loc -> RegM freeRegs () setAssigR assig = RegM $ \ s -> RA_Result s{ra_assig=assig} () +-- findVirtRegAny :: forall freeRegs u. Uniquable u +-- => u -> RegM freeRegs (Maybe Loc) +-- findVirtRegAny vreg = do +-- bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) +-- return $ foldr (findVirtRegAssig) Nothing bassig +-- where +-- findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe Loc -> Maybe Loc +-- findVirtRegAssig assig z = +-- lookupUFM (snd assig) vreg <|> z + +-- suggestAssig :: RegMap Loc -> RegM () +-- suggestAssig assig = RegM $ \ s -> +-- RA_Result s{ra_sugg_assig=plusUFM (ra_sugg_assig s) assig} () + +-- getSug :: Unique -> RegM Loc +-- getSug = RegM $ \ s at RA_State{ra_sugg_assig = sugg_assig} -> +-- RA_Result s sugg_assig + getBlockAssigR :: RegM freeRegs (BlockAssignment freeRegs) getBlockAssigR = RegM $ \ s at RA_State{ra_blockassig = assig} -> RA_Result s assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/utils/Outputable.hs ===================================== @@ -847,6 +847,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d8a84cbc5f3594db4a99c5805f570342aa6041af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d8a84cbc5f3594db4a99c5805f570342aa6041af You're receiving 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 7 14:26:28 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 07 Apr 2020 10:26:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18008 Message-ID: <5e8c8d9445fd4_6167136dfb9c3450023@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18008 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18008 You're receiving 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 7 14:56:25 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Tue, 07 Apr 2020 10:56:25 -0400 Subject: [Git][ghc/ghc][wip/T16806] Remove some unused definitions Message-ID: <5e8c94992ec55_6167e4e49b43458858@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: f933fd20 by Simon Jakobi at 2020-04-07T16:55:26+02:00 Remove some unused definitions - - - - - 3 changed files: - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Var/Env.hs Changes: ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -90,7 +90,7 @@ module GHC.Types.Name.Occurrence ( OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, extendOccSetList, unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, - isEmptyOccSet, intersectOccSet, intersectsOccSet, disjointOccSet, + isEmptyOccSet, intersectOccSet, filterOccSet, -- * Tidying up @@ -452,8 +452,6 @@ minusOccSet :: OccSet -> OccSet -> OccSet elemOccSet :: OccName -> OccSet -> Bool isEmptyOccSet :: OccSet -> Bool intersectOccSet :: OccSet -> OccSet -> OccSet -disjointOccSet :: OccSet -> OccSet -> Bool -intersectsOccSet :: OccSet -> OccSet -> Bool filterOccSet :: (OccName -> Bool) -> OccSet -> OccSet emptyOccSet = emptyUniqSet @@ -467,8 +465,6 @@ minusOccSet = minusUniqSet elemOccSet = elementOfUniqSet isEmptyOccSet = isEmptyUniqSet intersectOccSet = intersectUniqSets -disjointOccSet = disjointUniqSets -intersectsOccSet s1 s2 = not (s1 `disjointOccSet` s2) filterOccSet = filterUniqSet {- ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -45,7 +45,6 @@ module GHC.Types.Unique.DFM ( isNullUDFM, sizeUDFM, intersectUDFM, udfmIntersectUFM, - intersectsUDFM, disjointUDFM, disjointUdfmUfm, equalKeysUDFM, minusUDFM, @@ -318,9 +317,6 @@ udfmIntersectUFM (UDFM x i) y = UDFM (M.intersection x (ufmToIntMap y)) i -- M.intersection is left biased, that means the result will only have -- a subset of elements from the left set, so `i` is a good upper bound. -intersectsUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -intersectsUDFM x y = not (x `disjointUDFM` y) - disjointUDFM :: UniqDFM elt -> UniqDFM elt -> Bool disjointUDFM (UDFM x _i) (UDFM y _j) = M.disjoint x y ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -15,7 +15,7 @@ module GHC.Types.Var.Env ( plusVarEnv, plusVarEnv_C, plusVarEnv_CD, plusMaybeVarEnv_C, plusVarEnvList, alterVarEnv, delVarEnvList, delVarEnv, delVarEnv_Directly, - minusVarEnv, intersectsVarEnv, + minusVarEnv, lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv, mapVarEnv, zipVarEnv, modifyVarEnv, modifyVarEnv_Directly, @@ -476,7 +476,6 @@ restrictVarEnv :: VarEnv a -> VarSet -> VarEnv a delVarEnvList :: VarEnv a -> [Var] -> VarEnv a delVarEnv :: VarEnv a -> Var -> VarEnv a minusVarEnv :: VarEnv a -> VarEnv b -> VarEnv a -intersectsVarEnv :: VarEnv a -> VarEnv a -> Bool plusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a plusVarEnv_CD :: (a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a plusMaybeVarEnv_C :: (a -> a -> Maybe a) -> VarEnv a -> VarEnv a -> VarEnv a @@ -507,7 +506,6 @@ plusMaybeVarEnv_C = plusMaybeUFM_C delVarEnvList = delListFromUFM delVarEnv = delFromUFM minusVarEnv = minusUFM -intersectsVarEnv e1 e2 = not (e1 `disjointUFM` e2) plusVarEnv = plusUFM plusVarEnvList = plusUFMList lookupVarEnv = lookupUFM View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f933fd200d76d6169f2aef9ba383d6e3d2ce0c55 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f933fd200d76d6169f2aef9ba383d6e3d2ce0c55 You're receiving 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 7 14:59:40 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Tue, 07 Apr 2020 10:59:40 -0400 Subject: [Git][ghc/ghc][wip/T16806] Use Data.IntMap.disjoint Message-ID: <5e8c955c6b984_61673f81ef22dee43459388@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: e102273d by Simon Jakobi at 2020-04-07T16:59:28+02:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 17 changed files: - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Types/Module.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Set.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/ghc.cabal.in - compiler/iface/BuildTyCl.hs - compiler/typecheck/TcHoleErrors.hs - compiler/typecheck/TcSimplify.hs - hadrian/src/Rules/Documentation.hs Changes: ===================================== compiler/GHC/Core/Op/Specialise.hs ===================================== @@ -1173,7 +1173,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] is_flt_sc_arg var = isId var && not (isDeadBinder var) && isDictTy var_ty - && not (tyCoVarsOfType var_ty `intersectsVarSet` arg_set) + && tyCoVarsOfType var_ty `disjointVarSet` arg_set where var_ty = idType var @@ -2489,7 +2489,7 @@ filterCalls (CIS fn call_bag) dbs = extendVarSetList so_far (bindersOf db) | otherwise = so_far - ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) + ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set ---------------------- splitDictBinds :: Bag DictBind -> IdSet -> (Bag DictBind, Bag DictBind, IdSet) @@ -2519,7 +2519,7 @@ deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails deleteCallsMentioning bs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` bs) + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs deleteCallsFor :: [Id] -> CallDetails -> CallDetails -- Remove calls *for* bs ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -383,8 +383,8 @@ extendTCvSubstList subst tvs tys unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst -- Works when the ranges are disjoint unionTCvSubst (TCvSubst in_scope1 tenv1 cenv1) (TCvSubst in_scope2 tenv2 cenv2) - = ASSERT( not (tenv1 `intersectsVarEnv` tenv2) - && not (cenv1 `intersectsVarEnv` cenv2) ) + = ASSERT( tenv1 `disjointVarEnv` tenv2 + && cenv1 `disjointVarEnv` cenv2 ) TCvSubst (in_scope1 `unionInScope` in_scope2) (tenv1 `plusVarEnv` tenv2) (cenv1 `plusVarEnv` cenv2) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2112,7 +2112,7 @@ isValidJoinPointType arity ty where valid_under tvs arity ty | arity == 0 - = isEmptyVarSet (tvs `intersectVarSet` tyCoVarsOfType ty) + = tvs `disjointVarSet` tyCoVarsOfType ty | Just (t, ty') <- splitForAllTy_maybe ty = valid_under (tvs `extendVarSet` t) (arity-1) ty' | Just (_, res_ty) <- splitFunTy_maybe ty ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -1350,7 +1350,7 @@ glomSegments ctxt ((defs,uses,fwds,stmt) : segs) = (reverse yeses, reverse noes) where (noes, yeses) = span not_needed (reverse dus) - not_needed (defs,_,_,_) = not (intersectsNameSet defs uses) + not_needed (defs,_,_,_) = disjointNameSet defs uses ---------------------------------------------------- segsToStmts :: Stmt GhcRn body @@ -1908,7 +1908,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- then we have actually done some splitting. Otherwise it will go into -- an infinite loop (#14163). go lets indep bndrs ((L loc (BindStmt _ pat body bind_op fail_op), fvs): rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) && not (isStrictPattern pat) + | disjointNameSet bndrs fvs && not (isStrictPattern pat) = go lets ((L loc (BindStmt noExtField pat body bind_op fail_op), fvs) : indep) bndrs' rest where bndrs' = bndrs `unionNameSet` mkNameSet (collectPatBinders pat) @@ -1918,7 +1918,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- TODO: perhaps we shouldn't do this if there are any strict bindings, -- because we might be moving evaluation earlier. go lets indep bndrs ((L loc (LetStmt noExtField binds), fvs) : rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) + | disjointNameSet bndrs fvs = go ((L loc (LetStmt noExtField binds), fvs) : lets) indep bndrs rest go _ [] _ _ = Nothing go _ [_] _ _ = Nothing ===================================== compiler/GHC/Types/Module.hs ===================================== @@ -991,7 +991,7 @@ renameHoleUnitId' pkg_map env uid = IndefUnitId{ indefUnitIdComponentId = cid , indefUnitIdInsts = insts , indefUnitIdFreeHoles = fh }) - -> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env) + -> if disjointUdfmUfm (getUniqDSet fh) env then uid -- Functorially apply the substitution to the instantiation, -- then check the 'UnitInfoMap' to see if there is ===================================== compiler/GHC/Types/Name/Env.hs ===================================== @@ -140,7 +140,7 @@ delFromNameEnv x y = delFromUFM x y delListFromNameEnv x y = delListFromUFM x y filterNameEnv x y = filterUFM x y anyNameEnv f x = foldUFM ((||) . f) False x -disjointNameEnv x y = isNullUFM (intersectUFM x y) +disjointNameEnv x y = disjointUFM x y lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupNameEnv env n) ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -90,7 +90,7 @@ module GHC.Types.Name.Occurrence ( OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, extendOccSetList, unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, - isEmptyOccSet, intersectOccSet, intersectsOccSet, + isEmptyOccSet, intersectOccSet, filterOccSet, -- * Tidying up @@ -452,7 +452,6 @@ minusOccSet :: OccSet -> OccSet -> OccSet elemOccSet :: OccName -> OccSet -> Bool isEmptyOccSet :: OccSet -> Bool intersectOccSet :: OccSet -> OccSet -> OccSet -intersectsOccSet :: OccSet -> OccSet -> Bool filterOccSet :: (OccName -> Bool) -> OccSet -> OccSet emptyOccSet = emptyUniqSet @@ -466,7 +465,6 @@ minusOccSet = minusUniqSet elemOccSet = elementOfUniqSet isEmptyOccSet = isEmptyUniqSet intersectOccSet = intersectUniqSets -intersectsOccSet s1 s2 = not (isEmptyOccSet (s1 `intersectOccSet` s2)) filterOccSet = filterUniqSet {- ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Types.Name.Set ( emptyNameSet, unitNameSet, mkNameSet, unionNameSet, unionNameSets, minusNameSet, elemNameSet, extendNameSet, extendNameSetList, delFromNameSet, delListFromNameSet, isEmptyNameSet, filterNameSet, - intersectsNameSet, intersectNameSet, + intersectsNameSet, disjointNameSet, intersectNameSet, nameSetAny, nameSetAll, nameSetElemsStable, -- * Free variables @@ -65,6 +65,7 @@ delListFromNameSet :: NameSet -> [Name] -> NameSet filterNameSet :: (Name -> Bool) -> NameSet -> NameSet intersectNameSet :: NameSet -> NameSet -> NameSet intersectsNameSet :: NameSet -> NameSet -> Bool +disjointNameSet :: NameSet -> NameSet -> Bool -- ^ True if there is a non-empty intersection. -- @s1 `intersectsNameSet` s2@ doesn't compute @s2@ if @s1@ is empty @@ -81,10 +82,11 @@ elemNameSet = elementOfUniqSet delFromNameSet = delOneFromUniqSet filterNameSet = filterUniqSet intersectNameSet = intersectUniqSets +disjointNameSet = disjointUniqSets delListFromNameSet set ns = foldl' delFromNameSet set ns -intersectsNameSet s1 s2 = not (isEmptyNameSet (s1 `intersectNameSet` s2)) +intersectsNameSet s1 s2 = not (s1 `disjointNameSet` s2) nameSetAny :: (Name -> Bool) -> NameSet -> Bool nameSetAny = uniqSetAny ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -45,7 +45,6 @@ module GHC.Types.Unique.DFM ( isNullUDFM, sizeUDFM, intersectUDFM, udfmIntersectUFM, - intersectsUDFM, disjointUDFM, disjointUdfmUfm, equalKeysUDFM, minusUDFM, @@ -318,14 +317,11 @@ udfmIntersectUFM (UDFM x i) y = UDFM (M.intersection x (ufmToIntMap y)) i -- M.intersection is left biased, that means the result will only have -- a subset of elements from the left set, so `i` is a good upper bound. -intersectsUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -intersectsUDFM x y = isNullUDFM (x `intersectUDFM` y) - disjointUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -disjointUDFM (UDFM x _i) (UDFM y _j) = M.null (M.intersection x y) +disjointUDFM (UDFM x _i) (UDFM y _j) = M.disjoint x y disjointUdfmUfm :: UniqDFM elt -> UniqFM elt2 -> Bool -disjointUdfmUfm (UDFM x _i) y = M.null (M.intersection x (ufmToIntMap y)) +disjointUdfmUfm (UDFM x _i) y = M.disjoint x (ufmToIntMap y) minusUDFM :: UniqDFM elt1 -> UniqDFM elt2 -> UniqDFM elt1 minusUDFM (UDFM x i) (UDFM y _j) = UDFM (M.difference x y) i ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -241,7 +241,7 @@ intersectUFM_C intersectUFM_C f (UFM x) (UFM y) = UFM (M.intersectionWith f x y) disjointUFM :: UniqFM elt1 -> UniqFM elt2 -> Bool -disjointUFM (UFM x) (UFM y) = M.null (M.intersection x y) +disjointUFM (UFM x) (UFM y) = M.disjoint x y foldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a foldUFM k z (UFM m) = M.foldr k z m ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -27,6 +27,7 @@ module GHC.Types.Unique.Set ( unionUniqSets, unionManyUniqSets, minusUniqSet, uniqSetMinusUFM, intersectUniqSets, + disjointUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, elementOfUniqSet, @@ -105,6 +106,9 @@ minusUniqSet (UniqSet s) (UniqSet t) = UniqSet (minusUFM s t) intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a intersectUniqSets (UniqSet s) (UniqSet t) = UniqSet (intersectUFM s t) +disjointUniqSets :: UniqSet a -> UniqSet a -> Bool +disjointUniqSets (UniqSet s) (UniqSet t) = disjointUFM s t + restrictUniqSetToUFM :: UniqSet a -> UniqFM b -> UniqSet a restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -15,7 +15,7 @@ module GHC.Types.Var.Env ( plusVarEnv, plusVarEnv_C, plusVarEnv_CD, plusMaybeVarEnv_C, plusVarEnvList, alterVarEnv, delVarEnvList, delVarEnv, delVarEnv_Directly, - minusVarEnv, intersectsVarEnv, + minusVarEnv, lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv, mapVarEnv, zipVarEnv, modifyVarEnv, modifyVarEnv_Directly, @@ -476,7 +476,6 @@ restrictVarEnv :: VarEnv a -> VarSet -> VarEnv a delVarEnvList :: VarEnv a -> [Var] -> VarEnv a delVarEnv :: VarEnv a -> Var -> VarEnv a minusVarEnv :: VarEnv a -> VarEnv b -> VarEnv a -intersectsVarEnv :: VarEnv a -> VarEnv a -> Bool plusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a plusVarEnv_CD :: (a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a plusMaybeVarEnv_C :: (a -> a -> Maybe a) -> VarEnv a -> VarEnv a -> VarEnv a @@ -507,7 +506,6 @@ plusMaybeVarEnv_C = plusMaybeUFM_C delVarEnvList = delListFromUFM delVarEnv = delFromUFM minusVarEnv = minusUFM -intersectsVarEnv e1 e2 = not (isEmptyVarEnv (e1 `intersectUFM` e2)) plusVarEnv = plusUFM plusVarEnvList = plusUFMList lookupVarEnv = lookupUFM ===================================== compiler/ghc.cabal.in ===================================== @@ -66,7 +66,7 @@ Library bytestring >= 0.9 && < 0.11, binary == 0.8.*, time >= 1.4 && < 1.10, - containers >= 0.5 && < 0.7, + containers >= 0.6.2.1 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, template-haskell == 2.16.*, ===================================== compiler/iface/BuildTyCl.hs ===================================== @@ -164,8 +164,7 @@ mkDataConStupidTheta tycon arg_tys univ_tvs -- stupid theta, taken from the TyCon arg_tyvars = tyCoVarsOfTypes arg_tys - in_arg_tys pred = not $ isEmptyVarSet $ - tyCoVarsOfType pred `intersectVarSet` arg_tyvars + in_arg_tys pred = tyCoVarsOfType pred `intersectsVarSet` arg_tyvars ------------------------------------------------------ ===================================== compiler/typecheck/TcHoleErrors.hs ===================================== @@ -674,8 +674,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ctFreeVarSet = fvVarSet . tyCoFVsOfType . ctPred hole_fv_set = fvVarSet hole_fvs anyFVMentioned :: Ct -> Bool - anyFVMentioned ct = not $ isEmptyVarSet $ - ctFreeVarSet ct `intersectVarSet` hole_fv_set + anyFVMentioned ct = ctFreeVarSet ct `intersectsVarSet` hole_fv_set -- We filter out those constraints that have no variables (since -- they won't be solved by finding a type for the type variable -- representing the hole) and also other holes, since we're not ===================================== compiler/typecheck/TcSimplify.hs ===================================== @@ -2415,7 +2415,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs is_floatable :: VarSet -> Ct -> Bool is_floatable skols ct - | isDerivedCt ct = not (tyCoVarsOfCt ct `intersectsVarSet` skols) + | isDerivedCt ct = tyCoVarsOfCt ct `disjointVarSet` skols | otherwise = not (ctEvId ct `elemVarSet` skols) add_captured_ev_ids :: Cts -> VarSet -> VarSet ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -103,9 +103,8 @@ documentationRules = do -- include toplevel html target unless we neither want -- haddocks nor html pages produced by sphinx. - ++ [ html | Set.size (doctargets `Set.intersection` - Set.fromList [Haddocks, SphinxHTML] - ) > 0 ] + ++ [ html | Haddocks `Set.member` doctargets + || SphinxHTML `Set.member` doctargets ] -- include archives for whatever targets remain from -- the --docs arguments we got. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e102273dd00d25453270e9d81df57047b1f9183f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e102273dd00d25453270e9d81df57047b1f9183f You're receiving 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 7 15:00:07 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 07 Apr 2020 11:00:07 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Apply suggestion to compiler/GHC/Core/Op/ConstantFold.hs Message-ID: <5e8c9577c7e00_616776d1c7434615f6@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: c6955097 by Andreas Klebinger at 2020-04-07T11:00:00-04:00 Apply suggestion to compiler/GHC/Core/Op/ConstantFold.hs - - - - - 1 changed file: - compiler/GHC/Core/Op/ConstantFold.hs Changes: ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -1510,7 +1510,7 @@ match_eq_string _ _ _ _ = Nothing -- _ -> False -- -- Where knownString is one of: --- * (build ((unpackFoldrCString# "abc"#) +-- * (build (unpackFoldrCString# "abc"#)) -- * (unpackCString*# "abc"#) -- Limits matches to strings <=500 bytes. -- Also matches utf8 versions. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c69550976093dbd6ff4e3a4964058094489a321c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c69550976093dbd6ff4e3a4964058094489a321c You're receiving 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 7 15:38:35 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 07 Apr 2020 11:38:35 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Fix the perf regression in T12227/T12545 Message-ID: <5e8c9e7b89d29_616776d1c743474773@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 1d5f3fed by Sebastian Graf at 2020-04-07T17:38:11+02:00 Fix the perf regression in T12227/T12545 - - - - - 4 changed files: - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -27,6 +27,7 @@ import Data.List ( mapAccumL ) import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Core.Arity ( typeArity ) import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type @@ -152,7 +153,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +411,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -510,27 +511,63 @@ dmdTransform :: AnalEnv -- The strictness environment -- this function plus demand on its free variables dmdTransform env var dmd - | isDataConWorkId var -- Data constructor + -- Data constructors + | isDataConWorkId var = dmdTransformDataConSig (idArity var) (idStrictness var) dmd - + -- Dictionary component selectors | gopt Opt_DmdTxDictSel (ae_dflags env), - Just _ <- isClassOpId_maybe var -- Dictionary component selector + Just _ <- isClassOpId_maybe var = dmdTransformDictSelSig (idStrictness var) dmd - - | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + -- Imported functions + | isGlobalId var + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:import" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res - - | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing + -- Top-level or local let-bound thing for which we use LetDown ('useLetUp'). + -- In that case, we have a strictness signature to unleash in our AnalEnv. + | Just (sig, top_lvl) <- lookupSigEnv env var , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:LetDown" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl - then fn_ty -- Don't record top level things + then fn_ty -- Don't record demand on top-level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) - - | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + -- Everything else: + -- * Local let binders for which we use LetUp (cf. 'useLetUp') + -- * Lambda binders + -- * Case and constructor field binders + | let sig = mkConservativeSig env (idType var) + , let res = dmdTransformSig sig dmd + = -- pprTrace "dmdTransform:Other" (vcat [ppr var, ppr sig, ppr dmd, ppr res]) $ + addVarDmd res var (mkOnceUsedDmd dmd) + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig env (idType var) + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> Type -> StrictSig +mkConservativeSig env ty + -- Binders of unlifted types can't throw anything. This special case isn't + -- handled well by forcesRealWorld, which focuses on case scrutinees. + | unlifted = emptySig conDiv + -- no point in retaining cleared_sig when it's just Top + | no_change = topSig + | otherwise = cleared_sig + where + unlifted = isLiftedType_maybe ty == Just False + fam_envs = ae_fam_envs env + -- This is isomorphic to topSig. But this one has the right number of + -- arguments and will possibly have conDiv after the call to + -- tryClearPreciseException! + pessimistic_sig = StrictSig $ DmdType emptyVarEnv args topDiv + args = replicate (length (typeArity ty)) topDmd + -- In contrast to pessimistic_sig, cleared_sig might not have conDiv + -- Divergence! + cleared_sig = tryClearPreciseException fam_envs ty pessimistic_sig + sig_div = snd . splitStrictSig + no_change = sig_div cleared_sig == topDiv {- ************************************************************************ @@ -603,7 +640,7 @@ dmdFix top_lvl env let_dmd orig_pairs zapIdStrictness :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdStrictness pairs - = [(setIdStrictnessClearExn env id (emptySig topDiv), rhs) | (id, rhs) <- pairs ] + = [(setIdStrictnessClearExn env id topSig, rhs) | (id, rhs) <- pairs ] {- Note [Safe abortion in the fixed-point iteration] @@ -658,7 +695,7 @@ dmdAnalRhsLetDown rec_flag env let_dmd id rhs = mkRhsDmd env rhs_arity rhs (DmdType rhs_fv rhs_dmds rhs_div, rhs') = dmdAnal env rhs_dmd rhs - sig = mkStrictSigForArity rhs_arity (mkDmdType sig_fv rhs_dmds rhs_div) + sig = mkStrictSigForArity rhs_arity (DmdType sig_fv rhs_dmds rhs_div) id' = -- pprTraceWith "dmdAnalRhsLetDown" (\sig'-> ppr id <+> ppr sig <+> ppr sig') $ setIdStrictnessClearExn env id sig -- See Note [NOINLINE and strictness] @@ -944,9 +981,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -23,8 +23,7 @@ module GHC.Types.Demand ( DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType, BothDmdArg, mkBothDmdArg, toBothDmdArg, - emptyDmdType, botDmdType, mkDmdType, addDemand, - mayThrowPreciseDmdType, + emptyDmdType, botDmdType, addDemand, mayThrowPreciseDmdType, DmdEnv, emptyDmdEnv, peelFV, findIdDemand, @@ -33,7 +32,7 @@ module GHC.Types.Demand ( topDiv, botDiv, exnDiv, conDiv, appIsDeadEnd, isDeadEndSig, pprIfaceStrictSig, StrictSig(..), mkStrictSigForArity, mkClosedStrictSig, - emptySig, botSig, cprProdSig, + emptySig, topSig, botSig, cprProdSig, isTopSig, hasDemandEnvSig, splitStrictSig, strictSigDmdEnv, prependArgsStrictSig, etaConvertStrictSig, @@ -1275,6 +1274,9 @@ emptyDmdType div = DmdType emptyDmdEnv [] div botDmdType :: DmdType botDmdType = emptyDmdType botDiv +topDmdType :: DmdType +topDmdType = emptyDmdType topDiv + isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env @@ -1284,9 +1286,6 @@ mayThrowPreciseDmdType (DmdType _ _ Dunno) = True mayThrowPreciseDmdType (DmdType _ _ ExnOrDiv) = True mayThrowPreciseDmdType _ = False -mkDmdType :: DmdEnv -> [Demand] -> Divergence -> DmdType -mkDmdType fv ds res = DmdType fv ds res - dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1788,6 +1787,9 @@ emptySig div = StrictSig (emptyDmdType div) botSig :: StrictSig botSig = StrictSig botDmdType +topSig :: StrictSig +topSig = StrictSig topDmdType + cprProdSig :: Arity -> StrictSig cprProdSig _arity = emptySig conDiv -- constructor applications never throw precise exceptions ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -658,7 +658,7 @@ setIdCprInfo :: Id -> CprSig -> Id setIdCprInfo id sig = modifyIdInfo (\info -> setCprInfo info sig) id zapIdStrictness :: Id -> Id -zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` emptySig topDiv) id +zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id -- | This predicate says whether the 'Id' has a strict demand placed on it or -- has a type such that it can always be evaluated strictly (i.e an ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -324,7 +324,7 @@ vanillaIdInfo inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, - strictnessInfo = emptySig topDiv, + strictnessInfo = topSig, cprInfo = topCprSig, callArityInfo = unknownArity, levityInfo = NoLevityInfo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d5f3fed302beff21c539474cba46ece6d1f7e54 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d5f3fed302beff21c539474cba46ece6d1f7e54 You're receiving 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 7 16:06:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 07 Apr 2020 12:06:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: rts: ProfHeap: Fix memory leak when not compiled with profiling Message-ID: <5e8ca4fba937b_61673f81ef22dee434809c2@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - a620a1f5 by Ben Gamari at 2020-04-07T12:05:14-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 087e84e1 by Sylvain Henry at 2020-04-07T12:05:58-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Flags.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b305c46641f1b065e0fbc3f2cd37a89ad13ccb42...087e84e1c97dfd41ef4f3baaf810caef0b6a9c05 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b305c46641f1b065e0fbc3f2cd37a89ad13ccb42...087e84e1c97dfd41ef4f3baaf810caef0b6a9c05 You're receiving 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 7 19:04:41 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 07 Apr 2020 15:04:41 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Fix the perf regression in T12227/T12545 Message-ID: <5e8ccec9d0a6d_61673f8199536d94350982@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: be888031 by Sebastian Graf at 2020-04-07T21:03:31+02:00 Fix the perf regression in T12227/T12545 But now T9233 fails because we are doing more work. Temporarily marking as accepted increase. Metric Increase: T9233 - - - - - 4 changed files: - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -27,6 +27,7 @@ import Data.List ( mapAccumL ) import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Core.Arity ( typeArity ) import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type @@ -152,7 +153,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +411,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -510,27 +511,63 @@ dmdTransform :: AnalEnv -- The strictness environment -- this function plus demand on its free variables dmdTransform env var dmd - | isDataConWorkId var -- Data constructor + -- Data constructors + | isDataConWorkId var = dmdTransformDataConSig (idArity var) (idStrictness var) dmd - + -- Dictionary component selectors | gopt Opt_DmdTxDictSel (ae_dflags env), - Just _ <- isClassOpId_maybe var -- Dictionary component selector + Just _ <- isClassOpId_maybe var = dmdTransformDictSelSig (idStrictness var) dmd - - | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + -- Imported functions + | isGlobalId var + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:import" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res - - | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing + -- Top-level or local let-bound thing for which we use LetDown ('useLetUp'). + -- In that case, we have a strictness signature to unleash in our AnalEnv. + | Just (sig, top_lvl) <- lookupSigEnv env var , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:LetDown" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl - then fn_ty -- Don't record top level things + then fn_ty -- Don't record demand on top-level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) - - | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + -- Everything else: + -- * Local let binders for which we use LetUp (cf. 'useLetUp') + -- * Lambda binders + -- * Case and constructor field binders + | let sig = mkConservativeSig env (idType var) + , let res = dmdTransformSig sig dmd + = -- pprTrace "dmdTransform:Other" (vcat [ppr var, ppr sig, ppr dmd, ppr res]) $ + addVarDmd res var (mkOnceUsedDmd dmd) + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig env (idType var) + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> Type -> StrictSig +mkConservativeSig env ty + -- Binders of unlifted types can't throw anything. This special case isn't + -- handled well by forcesRealWorld, which focuses on case scrutinees. + | unlifted = emptySig conDiv + -- no point in retaining cleared_sig when it's just Top + | no_change = topSig + | otherwise = cleared_sig + where + unlifted = isLiftedType_maybe ty == Just False + fam_envs = ae_fam_envs env + -- This is isomorphic to topSig. But this one has the right number of + -- arguments and will possibly have conDiv after the call to + -- tryClearPreciseException! + pessimistic_sig = StrictSig $ DmdType emptyVarEnv args topDiv + args = replicate (length (typeArity ty)) topDmd + -- In contrast to pessimistic_sig, cleared_sig might not have conDiv + -- Divergence! + cleared_sig = tryClearPreciseException fam_envs ty pessimistic_sig + sig_div = snd . splitStrictSig + no_change = sig_div cleared_sig == topDiv {- ************************************************************************ @@ -603,7 +640,7 @@ dmdFix top_lvl env let_dmd orig_pairs zapIdStrictness :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdStrictness pairs - = [(setIdStrictnessClearExn env id (emptySig topDiv), rhs) | (id, rhs) <- pairs ] + = [(setIdStrictnessClearExn env id topSig, rhs) | (id, rhs) <- pairs ] {- Note [Safe abortion in the fixed-point iteration] @@ -658,7 +695,7 @@ dmdAnalRhsLetDown rec_flag env let_dmd id rhs = mkRhsDmd env rhs_arity rhs (DmdType rhs_fv rhs_dmds rhs_div, rhs') = dmdAnal env rhs_dmd rhs - sig = mkStrictSigForArity rhs_arity (mkDmdType sig_fv rhs_dmds rhs_div) + sig = mkStrictSigForArity rhs_arity (DmdType sig_fv rhs_dmds rhs_div) id' = -- pprTraceWith "dmdAnalRhsLetDown" (\sig'-> ppr id <+> ppr sig <+> ppr sig') $ setIdStrictnessClearExn env id sig -- See Note [NOINLINE and strictness] @@ -944,9 +981,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -23,8 +23,7 @@ module GHC.Types.Demand ( DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType, BothDmdArg, mkBothDmdArg, toBothDmdArg, - emptyDmdType, botDmdType, mkDmdType, addDemand, - mayThrowPreciseDmdType, + emptyDmdType, botDmdType, addDemand, mayThrowPreciseDmdType, DmdEnv, emptyDmdEnv, peelFV, findIdDemand, @@ -33,7 +32,7 @@ module GHC.Types.Demand ( topDiv, botDiv, exnDiv, conDiv, appIsDeadEnd, isDeadEndSig, pprIfaceStrictSig, StrictSig(..), mkStrictSigForArity, mkClosedStrictSig, - emptySig, botSig, cprProdSig, + emptySig, topSig, botSig, cprProdSig, isTopSig, hasDemandEnvSig, splitStrictSig, strictSigDmdEnv, prependArgsStrictSig, etaConvertStrictSig, @@ -1275,6 +1274,9 @@ emptyDmdType div = DmdType emptyDmdEnv [] div botDmdType :: DmdType botDmdType = emptyDmdType botDiv +topDmdType :: DmdType +topDmdType = emptyDmdType topDiv + isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env @@ -1284,9 +1286,6 @@ mayThrowPreciseDmdType (DmdType _ _ Dunno) = True mayThrowPreciseDmdType (DmdType _ _ ExnOrDiv) = True mayThrowPreciseDmdType _ = False -mkDmdType :: DmdEnv -> [Demand] -> Divergence -> DmdType -mkDmdType fv ds res = DmdType fv ds res - dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1788,6 +1787,9 @@ emptySig div = StrictSig (emptyDmdType div) botSig :: StrictSig botSig = StrictSig botDmdType +topSig :: StrictSig +topSig = StrictSig topDmdType + cprProdSig :: Arity -> StrictSig cprProdSig _arity = emptySig conDiv -- constructor applications never throw precise exceptions ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -658,7 +658,7 @@ setIdCprInfo :: Id -> CprSig -> Id setIdCprInfo id sig = modifyIdInfo (\info -> setCprInfo info sig) id zapIdStrictness :: Id -> Id -zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` emptySig topDiv) id +zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id -- | This predicate says whether the 'Id' has a strict demand placed on it or -- has a type such that it can always be evaluated strictly (i.e an ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -324,7 +324,7 @@ vanillaIdInfo inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, - strictnessInfo = emptySig topDiv, + strictnessInfo = topSig, cprInfo = topCprSig, callArityInfo = unknownArity, levityInfo = NoLevityInfo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be8880315dae91c5f84b27da88d96f4d08c77f2f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be8880315dae91c5f84b27da88d96f4d08c77f2f You're receiving 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 7 22:08:34 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 07 Apr 2020 18:08:34 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] 7 commits: Shortcut mkTvSubstPrs on empty list Message-ID: <5e8cf9e2474b5_6167e4e49b4354734@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: bd3df703 by Ben Gamari at 2020-03-26T14:49:24-04:00 Shortcut mkTvSubstPrs on empty list Surprisingly enough this reduces compilation time on Cabal by nearly 1%. - - - - - 854d9c44 by Ben Gamari at 2020-03-26T14:51:15-04:00 Shortcut coreView - - - - - 0f03145f by Ömer Sinan Ağacan at 2020-03-29T10:37:40-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 Previously if we had a ticky label for a proc, IdLabels for the ticky and proc would share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. - - - - - 21d40664 by Ben Gamari at 2020-04-07T15:01:05-04:00 expandSynTyCon_maybe: Special-case nullary tycons This avoids both allocation and some instructions. - - - - - e04955eb by Ben Gamari at 2020-04-07T16:58:21-04:00 Don't allow isConstraintKindTyCon to inline See #18026. - - - - - 7f1928db by Ben Gamari at 2020-04-07T16:58:48-04:00 Optimise tcView - - - - - d620e8e4 by Ben Gamari at 2020-04-07T17:00:29-04:00 Inline expandSynTyCon_maybe This is necessary to avoid some needless allocation since we currently lack nested CPR on sums. - - - - - 6 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/StgToCmm/Utils.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -108,7 +108,7 @@ module GHC.Cmm.CLabel ( pprCLabel, isInfoTableLabel, isConInfoTableLabel, - isIdLabel + isIdLabel, isTickyLabel ) where #include "HsVersions.h" @@ -268,6 +268,10 @@ isIdLabel :: CLabel -> Bool isIdLabel IdLabel{} = True isIdLabel _ = False +isTickyLabel :: CLabel -> Bool +isTickyLabel (IdLabel _ _ RednCounts) = True +isTickyLabel _ = False + -- This is laborious, but necessary. We can't derive Ord because -- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the -- implementation. See Note [No Ord for Unique] @@ -462,8 +466,7 @@ mkSRTLabel :: Unique -> CLabel mkSRTLabel u = SRTLabel u mkRednCountsLabel :: Name -> CLabel -mkRednCountsLabel name = - IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] +mkRednCountsLabel name = IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE] -- These have local & (possibly) external variants: mkLocalClosureLabel :: Name -> CafInfo -> CLabel ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -818,8 +818,13 @@ doSRTs dflags moduleSRTInfo procs data_ = do -- already updated by oneSRT srtMap CmmData _ (CmmStaticsRaw lbl _) - | isIdLabel lbl -> - -- not analysed by oneSRT, declare it non-CAFFY here + | isIdLabel lbl && not (isTickyLabel lbl) -> + -- Raw data are not analysed by oneSRT and they can't + -- be CAFFY. + -- Some ticky labels share the same Name with proc + -- labels so we don't update the SRT map for ticky + -- labels to avoid overriding CafInfos of procs. + -- See #17947. Map.insert (mkCAFLabel lbl) Nothing srtMap | otherwise -> -- Not an IdLabel, ignore ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -423,6 +423,7 @@ zipTCvSubst tcvs tys -- | Generates the in-scope set for the 'TCvSubst' from the types in the -- incoming environment. No CoVars, please! mkTvSubstPrs :: [(TyVar, Type)] -> TCvSubst +mkTvSubstPrs [] = emptyTCvSubst mkTvSubstPrs prs = ASSERT2( onlyTyVarsAndNoCoercionTy, text "prs" <+> ppr prs ) mkTvSubst in_scope tenv ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -2288,12 +2288,17 @@ expandSynTyCon_maybe -- ^ Expand a type synonym application, if any expandSynTyCon_maybe tc tys | SynonymTyCon { tyConTyVars = tvs, synTcRhs = rhs, tyConArity = arity } <- tc - = case tys `listLengthCmp` arity of - GT -> Just (tvs `zip` tys, rhs, drop arity tys) - EQ -> Just (tvs `zip` tys, rhs, []) - LT -> Nothing + = case tys of + [] -> Just ([], rhs, tys) + _ -> case tys `listLengthCmp` arity of + GT -> Just (tvs `zip` tys, rhs, drop arity tys) + EQ -> Just (tvs `zip` tys, rhs, []) + LT -> Nothing | otherwise = Nothing +{-# INLINE expandSynTyCon_maybe #-} +-- Inline to avoid allocation of tuples due to lack of nested CPR on sums. +-- Particularly relevant to coreView and tcView, which are hammered. ---------------- ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -355,8 +355,11 @@ See also #11715, which tracks removing this inconsistency. -- See also Note [coreView vs tcView] {-# INLINE tcView #-} tcView :: Type -> Maybe Type -tcView (TyConApp tc tys) | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys - = Just (mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys') +tcView (TyConApp tc tys) + | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys + = Just $ case tenv of + [] -> mkAppTys rhs tys' + _ -> mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys' -- The free vars of 'rhs' should all be bound by 'tenv', so it's -- ok to use 'substTy' here. -- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst. @@ -376,7 +379,9 @@ coreView :: Type -> Maybe Type -- joined onto the case analysis that the caller is already doing coreView ty@(TyConApp tc tys) | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys - = Just (mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys') + = Just $ case tenv of + [] -> mkAppTys rhs tys' + _ -> mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys' -- This equation is exactly like tcView -- At the Core level, Constraint = Type @@ -2936,6 +2941,7 @@ during type inference. isConstraintKindCon :: TyCon -> Bool isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey +{-# NOINLINE isConstraintKindCon #-} -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). ===================================== compiler/GHC/StgToCmm/Utils.hs ===================================== @@ -11,8 +11,8 @@ module GHC.StgToCmm.Utils ( cgLit, mkSimpleLit, - emitRawDataLits, mkRawDataLits, - emitRawRODataLits, mkRawRODataLits, + emitRawDataLits, + emitRawRODataLits, emitDataCon, emitRtsCall, emitRtsCallWithResult, emitRtsCallGen, assignTemp, newTemp, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f25cda0c941a6643c635eaa21803d7c2e50892c2...d620e8e4e9bdb479391a50967eaaad0996a71d9d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f25cda0c941a6643c635eaa21803d7c2e50892c2...d620e8e4e9bdb479391a50967eaaad0996a71d9d You're receiving 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 7 22:10:22 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 07 Apr 2020 18:10:22 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18023 Message-ID: <5e8cfa4e41c19_6167136dfb9c35480d3@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18023 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18023 You're receiving 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 7 22:36:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 07 Apr 2020 18:36:19 -0400 Subject: [Git][ghc/ghc][master] simplifier: Kill off ufKeenessFactor Message-ID: <5e8d006349408_616713503ee03570342@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 11 changed files: - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci.debugger/scripts/break021.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/plugins/all.T - testsuite/tests/simplCore/should_compile/T12600.hs - testsuite/tests/simplCore/should_compile/T15056.stderr - testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/T4306.hs Changes: ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1002,10 +1002,6 @@ ufUseThreshold At a call site, if the unfolding, less discounts, is smaller than this, then it's small enough inline -ufKeenessFactor - Factor by which the discounts are multiplied before - subtracting from size - ufDictDiscount The discount for each occurrence of a dictionary argument as an argument of a class method. Should be pretty small @@ -1024,6 +1020,22 @@ ufVeryAggressive loop breakers. +Historical Note: Before April 2020 we had another factor, +ufKeenessFactor, which would scale the discounts before they were subtracted +from the size. This was justified with the following comment: + + -- We multiply the raw discounts (args_discount and result_discount) + -- ty opt_UnfoldingKeenessFactor because the former have to do with + -- *size* whereas the discounts imply that there's some extra + -- *efficiency* to be gained (e.g. beta reductions, case reductions) + -- by inlining. + +However, this is highly suspect since it means that we subtract a *scaled* size +from an absolute size, resulting in crazy (e.g. negative) scores in some cases +(#15304). We consequently killed off ufKeenessFactor and bumped up the +ufUseThreshold to compensate. + + Note [Function applications] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a function application (f a b) @@ -1307,8 +1319,7 @@ tryUnfolding dflags id lone_variable extra_doc = text "discounted size =" <+> int discounted_size discounted_size = size - discount small_enough = discounted_size <= ufUseThreshold dflags - discount = computeDiscount dflags arg_discounts - res_discount arg_infos cont_info + discount = computeDiscount arg_discounts res_discount arg_infos cont_info where mk_doc some_benefit extra_doc yes_or_no @@ -1553,14 +1564,9 @@ which Roman did. -} -computeDiscount :: DynFlags -> [Int] -> Int -> [ArgSummary] -> CallCtxt +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt -> Int -computeDiscount dflags arg_discounts res_discount arg_infos cont_info - -- We multiple the raw discounts (args_discount and result_discount) - -- ty opt_UnfoldingKeenessFactor because the former have to do with - -- *size* whereas the discounts imply that there's some extra - -- *efficiency* to be gained (e.g. beta reductions, case reductions) - -- by inlining. +computeDiscount arg_discounts res_discount arg_infos cont_info = 10 -- Discount of 10 because the result replaces the call -- so we count 10 for the function itself @@ -1569,8 +1575,7 @@ computeDiscount dflags arg_discounts res_discount arg_infos cont_info -- Discount of 10 for each arg supplied, -- because the result replaces the call - + round (ufKeenessFactor dflags * - fromIntegral (total_arg_discount + res_discount')) + + total_arg_discount + res_discount' where actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos total_arg_discount = sum actual_arg_discounts ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -699,7 +699,6 @@ data DynFlags = DynFlags { ufUseThreshold :: Int, ufFunAppDiscount :: Int, ufDictDiscount :: Int, - ufKeenessFactor :: Float, ufDearOp :: Int, ufVeryAggressive :: Bool, @@ -1430,12 +1429,11 @@ defaultDynFlags mySettings llvmConfig = -- into Csg.calc (The unfolding for sqr never makes it into the -- interface file.) ufCreationThreshold = 750, - ufUseThreshold = 60, + ufUseThreshold = 80, ufFunAppDiscount = 60, -- Be fairly keen to inline a function if that means -- we'll be able to pick the right method from a dictionary ufDictDiscount = 30, - ufKeenessFactor = 1.5, ufDearOp = 40, ufVeryAggressive = False, @@ -3023,8 +3021,9 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d {ufFunAppDiscount = n})) , make_ord_flag defFlag "funfolding-dict-discount" (intSuffix (\n d -> d {ufDictDiscount = n})) - , make_ord_flag defFlag "funfolding-keeness-factor" - (floatSuffix (\n d -> d {ufKeenessFactor = n})) + , make_dep_flag defFlag "funfolding-keeness-factor" + (floatSuffix (\_ d -> d)) + "-funfolding-keeness-factor is no longer respected as of GHC 8.12" , make_ord_flag defFlag "fmax-worker-args" (intSuffix (\n d -> d {maxWorkerArgs = n})) , make_ord_flag defGhciFlag "fghci-hist-size" ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140082 + Total ticks: 140084 ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -75,7 +75,8 @@ test('break015', expect_broken(1532), ghci_script, ['break015.script']) test('break016', combined_output, ghci_script, ['break016.script']) test('break017', [extra_files(['../QSort.hs']), combined_output], ghci_script, ['break017.script']) -test('break018', extra_files(['../mdo.hs']), ghci_script, ['break018.script']) +test('break018', [expect_broken(18004), extra_files(['../mdo.hs'])], + ghci_script, ['break018.script']) test('break019', extra_files(['../Test2.hs']), ghci_script, ['break019.script']) test('break020', extra_files(['Break020b.hs']), ghci_script, ['break020.script']) test('break021', extra_files(['Break020b.hs', 'break020.hs']), ghci_script, ['break021.script']) ===================================== testsuite/tests/ghci.debugger/scripts/break021.stdout ===================================== @@ -41,7 +41,7 @@ _result :: IO () = _ ^^^^^^^^^^^^^^^^^ 13 in_another_module 0 Stopped in Main.in_another_decl, break020.hs:(6,21)-(7,30) -_result :: m () = _ +_result :: IO () = _ 5 vv 6 in_another_decl _ = do line1 0 @@ -49,7 +49,7 @@ _result :: m () = _ ^^ 8 Stopped in Main.in_another_decl, break020.hs:6:24-30 -_result :: m () = _ +_result :: IO () = _ 5 6 in_another_decl _ = do line1 0 ^^^^^^^ @@ -61,7 +61,7 @@ _result :: IO () = _ ^^^^^^^^^ 4 line2 _ = return () Stopped in Main.in_another_decl, break020.hs:7:24-30 -_result :: m () = _ +_result :: IO () = _ 6 in_another_decl _ = do line1 0 7 line2 0 ^^^^^^^ ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -64,80 +64,34 @@ Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: ># (BUILTIN) Rule fired: ==# (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) +Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) -Rule fired: Class op return (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: Class op pure (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op return (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op >>= (BUILTIN) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) -Rule fired: Class op $p1Monad (BUILTIN) -Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) -Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) +Rule fired: Class op return (BUILTIN) ===================================== testsuite/tests/plugins/all.T ===================================== @@ -167,7 +167,6 @@ test('plugin-recomp-flags', test('plugin-recomp-change', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}') ], makefile_test, []) @@ -175,7 +174,6 @@ test('plugin-recomp-change', test('plugin-recomp-change-prof', [extra_files(['plugin-recomp/', 'plugin-recomp-test.hs']), only_ways([config.ghc_plugin_way]), - when(compiler_debugged(), expect_broken_for(17308, ['dyn'])), pre_cmd('$MAKE -s --no-print-directory -C plugin-recomp package.plugins01 TOP={top}'), when(not config.have_profiling,skip) ], ===================================== testsuite/tests/simplCore/should_compile/T12600.hs ===================================== @@ -27,3 +27,4 @@ instance (Eq1 f) => Eq1 (G f) where foo :: G F Int -> G F Int -> Bool foo a b = eq1 a b +{-# NOINLINE foo #-} ===================================== testsuite/tests/simplCore/should_compile/T15056.stderr ===================================== @@ -1,9 +1,7 @@ Rule fired: Class op - (BUILTIN) Rule fired: Class op + (BUILTIN) Rule fired: Class op + (BUILTIN) -Rule fired: Class op enumFromTo (BUILTIN) -Rule fired: Class op foldr (BUILTIN) -Rule fired: Class op foldr (BUILTIN) Rule fired: +# (BUILTIN) Rule fired: Class op foldr (BUILTIN) +Rule fired: Class op enumFromTo (BUILTIN) Rule fired: fold/build (GHC.Base) ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -1,4 +1,5 @@ RULES: "SPEC $cm @()" [0] RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] +"SPEC/T17966 $fShowMaybe_$cshow @Integer" "SPEC/T17966 $fShowMaybe_$cshowList @Integer" "SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/T4306.hs ===================================== @@ -10,3 +10,4 @@ upd (UPD _ (D x _)) = sqrt $! (x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x + x*x + x*x + sin x + x*x + x*x + cos x + x*x + x*x + tan x) -- make the rhs large enough to be worker/wrapperred +{-# NOINLINE upd #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d2991f8b4c1b686323b2c9452ce845a60b8d94c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d2991f8b4c1b686323b2c9452ce845a60b8d94c You're receiving 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 7 22:37:00 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 07 Apr 2020 18:37:00 -0400 Subject: [Git][ghc/ghc][master] Modules: type-checker (#13009) Message-ID: <5e8d008c69b93_61673f81cc90b39c357435a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Hooks.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/255418da5d264fb2758bc70925adb2094f34adc3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/255418da5d264fb2758bc70925adb2094f34adc3 You're receiving 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 7 23:43:39 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 07 Apr 2020 19:43:39 -0400 Subject: [Git][ghc/ghc][wip/strict-NoExtCon] 32 commits: Clean up "Eta reduction for data families" Notes Message-ID: <5e8d102b87629_61673f81cc90b39c35787d4@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/strict-NoExtCon at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ae1e0f5e73c0fd3f81e43d347a9c38f63edc23b...04b6cf947ea065a210a216cc91f918cc1660d430 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ae1e0f5e73c0fd3f81e43d347a9c38f63edc23b...04b6cf947ea065a210a216cc91f918cc1660d430 You're receiving 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 7 23:48:06 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 07 Apr 2020 19:48:06 -0400 Subject: [Git][ghc/ghc][wip/T18023] 5 commits: rts: ProfHeap: Fix memory leak when not compiled with profiling Message-ID: <5e8d11369a587_61673f81ef22dee43579682@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18023 at Glasgow Haskell Compiler / GHC Commits: f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 6c697c24 by Ryan Scott at 2020-04-07T19:45:59-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.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/d3706e35310d150f6ecb4eeade0c3e1b7108d9cf...6c697c24cda33fb7ec5b9ff36188584ea8d3e81a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3706e35310d150f6ecb4eeade0c3e1b7108d9cf...6c697c24cda33fb7ec5b9ff36188584ea8d3e81a You're receiving 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 8 07:45:07 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 08 Apr 2020 03:45:07 -0400 Subject: [Git][ghc/ghc][wip/T16992] 596 commits: Remove prefix arrow support for GADTs (#17211) Message-ID: <5e8d81032b160_61673f81cc90b39c3593937@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/T16992 at Glasgow Haskell Compiler / GHC Commits: 8b8dc366 by Krzysztof Gogolewski at 2019-11-25T14:37:38+01:00 Remove prefix arrow support for GADTs (#17211) This reverts the change in #9096. The specialcasing done for prefix (->) is brittle and does not support VTA, type families, type synonyms etc. - - - - - 5a08f7d4 by Sebastian Graf at 2019-11-27T00:14:59-05:00 Make warnings for TH splices opt-in In #17270 we have the pattern-match checker emit incorrect warnings. The reason for that behavior is ultimately an inconsistency in whether we treat TH splices as written by the user (`FromSource :: Origin`) or as generated code (`Generated`). This was first reported in #14838. The current solution is to TH splices as `Generated` by default and only treat them as `FromSource` when the user requests so (-fenable-th-splice-warnings). There are multiple reasons for opt-in rather than opt-out: * It's not clear that the user that compiles a splice is the author of the code that produces the warning. Think of the situation where she just splices in code from a third-party library that produces incomplete pattern matches. In this scenario, the user isn't even able to fix that warning. * Gathering information for producing the warnings (pattern-match check warnings in particular) is costly. There's no point in doing so if the user is not interested in those warnings. Fixes #17270, but not #14838, because the proper solution needs a GHC proposal extending the TH AST syntax. - - - - - 8168b42a by Vladislav Zavialov at 2019-11-27T11:32:18+03:00 Whitespace-sensitive bang patterns (#1087, #17162) This patch implements a part of GHC Proposal #229 that covers five operators: * the bang operator (!) * the tilde operator (~) * the at operator (@) * the dollar operator ($) * the double dollar operator ($$) Based on surrounding whitespace, these operators are disambiguated into bang patterns, lazy patterns, strictness annotations, type applications, splices, and typed splices. This patch doesn't cover the (-) operator or the -Woperator-whitespace warning, which are left as future work. - - - - - 9e5477c4 by Ryan Scott at 2019-11-27T20:01:50-05:00 Fix @since annotations for isResourceVanishedError and friends (#17488) - - - - - e122ba33 by Sergei Trofimovich at 2019-11-27T20:02:29-05:00 .gitmodules: tweak 'exception' URL to avoid redirection warnings Avoid initial close warning of form: ``` Cloning into 'exceptions'... warning: redirecting to https://gitlab.haskell.org/ghc/packages/exceptions.git/ ``` Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f84b52a by Philipp Krüger at 2019-11-28T02:54:05-05:00 Reduce boolean blindness in OccInfo(OneOcc) #17482 * Transformed the type aliases `InterestingCxt`, `InsideLam` and `OneBranch` into data types. * Added Semigroup and Monoid instances for use in orOccInfo in OccurAnal.hs * Simplified some usage sites by using pattern matching instead of boolean algebra. Metric Increase: T12150 This increase was on a Mac-build of exactly 1%. This commit does *not* re-intruduce the asymptotic memory usage described in T12150. - - - - - 3748ba3a by Brian Wignall at 2019-11-28T02:54:52-05:00 Fix typos, using Wikipedia list of common typos - - - - - 6c59cc71 by Stefan Schulze Frielinghaus at 2019-11-28T02:55:33-05:00 Fix endian handling of LLVM backend Get rid of CPP macro WORDS_BIGENDIAN which is not defined anymore, and replace it by DynFlag. This fixes partially #17337. - - - - - 6985e0fc by Vladislav Zavialov at 2019-11-28T15:47:53+03:00 Factor out HsSCC/HsCoreAnn/HsTickPragma into HsPragE This is a refactoring with no user-visible changes (except for GHC API users). Consider the HsExpr constructors that correspond to user-written pragmas: HsSCC representing {-# SCC ... #-} HsCoreAnn representing {-# CORE ... #-} HsTickPragma representing {-# GENERATED ... #-} We can factor them out into a separate datatype, HsPragE. It makes the code a bit tidier, especially in the parser. Before this patch: hpc_annot :: { Located ( (([AddAnn],SourceText),(StringLiteral,(Int,Int),(Int,Int))), ((SourceText,SourceText),(SourceText,SourceText)) ) } After this patch: prag_hpc :: { Located ([AddAnn], HsPragE GhcPs) } - - - - - 7f695a20 by Ömer Sinan Ağacan at 2019-11-29T08:25:28-05:00 Pass ModDetails with (partial) ModIface in HscStatus (Partial) ModIface and ModDetails are generated at the same time, but they're passed differently: ModIface is passed in HscStatus consturctors while ModDetails is returned in a tuple. This refactors ModDetails passing so that it's passed around with ModIface in HscStatus constructors. This makes the code more consistent and hopefully easier to understand: ModIface and ModDetails are really very closely related. It makes sense to treat them the same way. - - - - - e921c90f by Ömer Sinan Ağacan at 2019-11-29T08:26:07-05:00 Improve few Foreign.Marshal.Utils docs In copyBytes and moveBytes mention which argument is source and which is destination. Also fixes some of the crazy indentation in the module and cleans trailing whitespace. - - - - - 316f2431 by Sebastian Graf at 2019-11-30T02:57:58-05:00 Hadrian docs: Rename the second "validate" entry to "slow-validate" [ci skip] That would be in line with the implementation. - - - - - 5aba5d32 by Vladislav Zavialov at 2019-11-30T02:58:34-05:00 Remove HasSrcSpan (#17494) Metric Decrease: haddock.compiler - - - - - d1de5c22 by Sylvain Henry at 2019-11-30T02:59:13-05:00 Use Hadrian by default in validate script (#17527) - - - - - 3a96a0b6 by Sebastian Graf at 2019-11-30T02:59:55-05:00 Simpler Semigroup instance for InsideLam and InterestingCtxt This mirrors the definition of `(&&)` and `(||)` now, relieving the Simplifier of a marginal amount of pressure. - - - - - f8cfe81a by Roland Senn at 2019-11-30T20:33:49+01:00 Improve tests for #17171 While backporting MR !1806 to 8.8.2 (!1885) I learnt the following: * Tests with `expect_fail` do not compare `*.stderr` output files. So a test using `expect_fail` will not detect future regressions on the `stderr` output. * To compare the `*.stderr` output files, I have to use the `exit_code(n)` function. * When a release is made, tests with `makefile_test` are converted to use `run_command`. * For the test `T17171a` the return code is `1` when running `makefile_test`, however it's `2` when running `run_command`. Therefore I decided: * To improve my tests for #17171 * To change test T17171a from `expect_fail` to `exit_code(2)` * To change both tests from `makefile_test` to `run_command` - - - - - 2b113fc9 by Vladislav Zavialov at 2019-12-01T08:17:05-05:00 Update DisambECP-related comments - - - - - beed7c3e by Ben Gamari at 2019-12-02T03:41:37-05:00 testsuite: Fix location of typing_stubs module This should fix the build on Debian 8. - - - - - 53251413 by Ben Gamari at 2019-12-02T03:42:14-05:00 testsuite: Don't override LD_LIBRARY_PATH, only prepend NixOS development environments often require that LD_LIBRARY_PATH be set in order to find system libraries. T1407 was overriding LD_LIBRARY_PATH, dropping these directories. Now it merely prepends, its directory. - - - - - 65400314 by Krzysztof Gogolewski at 2019-12-02T03:42:57-05:00 Convert warnings into assertions Since the invariants always hold in the testsuite, we can convert them to asserts. - - - - - 18baed64 by Alan Zimmerman at 2019-12-02T03:43:37-05:00 API Annotations: Unicode '->' on HsForallTy The code fragment type family Proxy2' ∷ ∀ k → k → Type where Proxy2' = Proxy' Generates AnnRarrow instead of AnnRarrowU for the first →. Fixes #17519 - - - - - 717f3236 by Brian Wignall at 2019-12-02T03:44:16-05:00 Fix more typos - - - - - bde48f8e by Ben Gamari at 2019-12-02T11:55:34-05:00 More Haddock syntax in GHC.Hs.Utils As suggested by RyanGlScott in !2163. - - - - - 038bedbc by Ben Gamari at 2019-12-02T11:56:18-05:00 Simplify: Fix pretty-printing of strictness A colleague recently hit the panic in Simplify.addEvals and I noticed that the message is quite unreadable due to incorrect pretty-printing. Fix this. - - - - - c500f652 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix changelog linting logic - - - - - 8ead967d by Ben Gamari at 2019-12-02T11:56:54-05:00 win32-init: Drop workaround for #17480 The `process` changes have now been merged into `hsc2hs`. (cherry picked from commit fa029f53132ad59f847ed012d3b835452cf16615) - - - - - d402209a by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Disable Sphinx build on Debian 8 The docutils version available appears to be too old to support the `table` directive's `:widths:` options. (cherry picked from commit 75764487a96a7a026948b5af5022781872d12baa) - - - - - f1f68824 by Ben Gamari at 2019-12-02T11:56:54-05:00 base: Fix <unistd.h> #include Previously we were including <sys/unistd.h> which is available on glibc but not musl. (cherry picked from commit e44b695ca7cb5f3f99eecfba05c9672c6a22205e) - - - - - 37eb94b3 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Bump Docker images Installs pxz on Centos7 (cherry picked from commit 86960e691f7a600be247c32a7cf795bf9abf7cc4) - - - - - aec98a79 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: pxz is unavailable on CentOS 7 Fall back to xz - - - - - 6708b8e5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Set LANG on CentOS 7 It otherwise seems to default to ascii - - - - - 470ef0e7 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Consolidate release build configuration - - - - - 38338757 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add Debian 10 builds - - - - - 012f13b5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix Windows bindist collection Apparently variable interpolation in the `artifacts.paths` key of `gitlab-ci.yml` doesn't work on Windows as it does on WIndows. (cherry picked from commit 100cc756faa4468ed6950116bae30609c1c3468b) - - - - - a0f09e23 by Ben Gamari at 2019-12-02T11:56:54-05:00 testsuite: Simplify Python <3.5 fallback for TextIO (cherry picked from commit d092d8598694c23bc07cdcc504dff52fa5f33be1) - - - - - 2b2370ec by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add release-x86_64-linux-deb9 job (cherry picked from commit cbedb3c4a90649f474cb716842ba53afc5a642ca) - - - - - b1c206fd by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Always build source tarball (cherry picked from commit 67b5de88ef923971f1980335137e3c7193213abd) - - - - - 4cbd5b47 by Sergei Trofimovich at 2019-12-02T11:57:33-05:00 configure.ac: make cross-compiler detection stricter Be more precise at detecting cross-compilation case. Before the change configuration $ ./configure --host=x86_64-pc-linux-gnu --target=x86_64-gentoo-linux-musl was not considered a cross-target. Even though libcs are different (`glibc` vs. `musl`). Without this patch build fails as: ``` "inplace/bin/ghc-cabal" check libraries/integer-gmp "inplace/bin/ghc-cabal" configure libraries/integer-gmp dist-install \ --with-ghc="/home/slyfox/dev/git/ghc/inplace/bin/ghc-stage1" \ --with-ghc-pkg="/home/slyfox/dev/git/ghc/inplace/bin/ghc-pkg" \ --disable-library-for-ghci --enable-library-vanilla --enable-library-for-ghci \ --enable-library-profiling --enable-shared --with-hscolour="/usr/bin/HsColour" \ --configure-option=CFLAGS="-Wall \ -Werror=unused-but-set-variable -Wno-error=inline \ -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp" \ --configure-option=LDFLAGS=" " --configure-option=CPPFLAGS=" \ " --gcc-options="-Wall -Werror=unused-but-set-variable -Wno-error=inline -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp \ " --with-gcc="x86_64-gentoo-linux-musl-gcc" --with-ld="x86_64-gentoo-linux-musl-ld.gold" --with-ar="x86_64-gentoo-linux-musl-ar" \ --with-alex="/usr/bin/alex" --with-happy="/usr/bin/happy" Configuring integer-gmp-1.0.2.0... configure: WARNING: unrecognized options: --with-compiler checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking target system type... x86_64-pc-linux-gnu checking for gcc... /usr/lib/ccache/bin/x86_64-gentoo-linux-musl-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... configure: error: in `/home/slyfox/dev/git/ghc/libraries/integer-gmp/dist-install/build': configure: error: cannot run C compiled programs. If you meant to cross compile, use `--host'. See `config.log' for more details make[1]: *** [libraries/integer-gmp/ghc.mk:5: libraries/integer-gmp/dist-install/package-data.mk] Error 1 make: *** [Makefile:126: all] Error 2 ``` Note: here `ghc-stage1` is assumed to target `musl` target but is passed `glibc` toolchain. It happens because initial ./configure phase did not detect host/target as different. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f7cb423 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Add `timesInt2#` primop - - - - - fbbe18a2 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Use the new timesInt2# primop in integer-gmp (#9431) - - - - - 5a4b8d0c by Athas at 2019-12-03T00:00:09-05:00 Document RTS behaviour upon encountering '--'. - - - - - 705a16df by Ben Gamari at 2019-12-03T07:11:33-05:00 Make BCO# lifted In #17424 Simon PJ noted that there is a potentially unsafe occurrence of unsafeCoerce#, coercing from an unlifted to lifted type. However, nowhere in the compiler do we assume that a BCO# is not a thunk. Moreover, in the case of a CAF the result returned by `createBCO` *will* be a thunk (as noted in [Updatable CAF BCOs]). Consequently it seems better to rather make BCO# a lifted type and rename it to BCO. - - - - - 35afe4f3 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Use Int# primops in `Bits Int{8,16,32,64}` instances - - - - - 7a51b587 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Add constant folding rule (#16402) narrowN (x .&. m) m .&. (2^N-1) = 2^N-1 ==> narrowN x e.g. narrow16 (x .&. 0x12FFFF) ==> narrow16 x - - - - - 10caee7f by Ben Gamari at 2019-12-03T21:04:50-05:00 users-guide: Add 8.12.1 release notes - - - - - 25019d18 by Ben Gamari at 2019-12-03T21:04:50-05:00 Drop Uniquable constraint for AnnTarget This relied on deriveUnique, which was far too subtle to be safely applied. Thankfully the instance doesn't appear to be used so let's just drop it. - - - - - 78b67ad0 by Ben Gamari at 2019-12-03T21:04:50-05:00 Simplify uniqAway This does two things: * Eliminate all uses of Unique.deriveUnique, which was quite easy to mis-use and extremely subtle. * Rename the previous "derived unique" notion to "local unique". This is possible because the only places where `uniqAway` can be safely used are those where local uniqueness (with respect to some InScopeSet) is sufficient. * Rework the implementation of VarEnv.uniqAway, as discussed in #17462. This should make the operation significantly more efficient than its previous iterative implementation.. Metric Decrease: T9872c T12227 T9233 T14683 T5030 T12545 hie002 Metric Increase: T9961 - - - - - f03a41d4 by Ben Gamari at 2019-12-03T21:05:27-05:00 Elf: Fix link info note generation Previously we would use the `.int` assembler directive to generate 32-bit words in the note section. However, `.int` is note guaranteed to produce 4-bytes; in fact, on some platforms (e.g. AArch64) it produces 8-bytes. Use the `.4bytes` directive to avoid this. Moreover, we used the `.align` directive, which is quite platform dependent. On AArch64 it appears to not even be idempotent (despite what the documentation claims). `.balign` is consequentially preferred as it offers consistent behavior across platforms. - - - - - 84585e5e by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Meaning-preserving SCC annotations (#15730) This patch implements GHC Proposal #176: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0176-scc-parsing.rst Before the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = 1.0 After the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = parse error - - - - - e49e5470 by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Improve error messages for SCC pragmas - - - - - a2b535d9 by Ben Gamari at 2019-12-05T16:07:45-05:00 users guide: Try to silence underfull \hbox warnings We use two tricks, as suggested here [1]: * Use microtype to try to reduce the incidence of underfull boxes * Bump up \hbadness to eliminate the warnings - - - - - 4e47217f by Bodigrim at 2019-12-05T16:07:47-05:00 Make sameNat and sameSymbol proxy-polymorphic - - - - - 8324f0b7 by Bodigrim at 2019-12-05T16:07:47-05:00 Test proxy-polymorphic sameNat and sameSymbol - - - - - 69001f54 by Ben Gamari at 2019-12-05T16:07:48-05:00 nonmoving: Clear segment bitmaps during sweep Previously we would clear the bitmaps of segments which we are going to sweep during the preparatory pause. However, this is unnecessary: the existence of the mark epoch ensures that the sweep will correctly identify non-reachable objects, even if we do not clear the bitmap. We now defer clearing the bitmap to sweep, which happens concurrently with mutation. - - - - - 58a9c429 by Ben Gamari at 2019-12-05T16:07:48-05:00 testsuite: Disable divByZero on non-NCG targets The LLVM backend does not guarantee any particular semantics for division by zero, making this test unreliable across platforms. - - - - - 8280bd8a by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Factor out terminal coloring - - - - - 92a52aaa by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Make performance metric summary more readable Along with some refactoring. - - - - - c4ca29c7 by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Use colors more consistently - - - - - 3354c68e by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Pretty-printing of the * kind Before this patch, GHC always printed the * kind unparenthesized. This led to two issues: 1. Sometimes GHC printed invalid or incorrect code. For example, GHC would print: type F @* x = x when it meant to print: type F @(*) x = x In the former case, instead of a kind application we were getting a type operator (@*). 2. Sometimes GHC printed kinds that were correct but hard to read. Should Either * Int be read as Either (*) Int or as (*) Either Int ? This depends on whether -XStarIsType is enabled, but it would be easier if we didn't have to check for the flag when reading the code. We can solve both problems by assigning (*) a different precedence. Note that Haskell98 kinds are not affected: ((* -> *) -> *) -> * does NOT become (((*) -> (*)) -> (*)) -> (*) The parentheses are added when (*) is used in a function argument position: F * * * becomes F (*) (*) (*) F A * B becomes F A (*) B Proxy * becomes Proxy (*) a * -> * becomes a (*) -> * - - - - - 70dd0e4b by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Parenthesize the * kind in TH.Ppr - - - - - a7a4efbf by Ben Gamari at 2019-12-05T16:07:49-05:00 rts/NonMovingSweep: Fix locking of new mutable list allocation Previously we used allocBlockOnNode_sync in nonmovingSweepMutLists despite the fact that we aren't in the GC and therefore the allocation spinlock isn't in use. This meant that sweep would end up spinning until the next minor GC, when the SM lock was moved away from the SM_MUTEX to the spinlock. This isn't a correctness issue but it sure isn't good for performance. Found thanks for Ward. Fixes #17539. - - - - - f171b358 by Matthias Braun at 2019-12-05T16:07:51-05:00 Fix typo in documentation of Base.hs. - - - - - 9897e8c8 by Gabor Greif at 2019-12-06T21:20:38-05:00 Implement pointer tagging for big families (#14373) Formerly we punted on these and evaluated constructors always got a tag of 1. We now cascade switches because we have to check the tag first and when it is MAX_PTR_TAG then get the precise tag from the info table and switch on that. The only technically tricky part is that the default case needs (logical) duplication. To do this we emit an extra label for it and branch to that from the second switch. This avoids duplicated codegen. Here's a simple example of the new code gen: data D = D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 On a 64-bit system previously all constructors would be tagged 1. With the new code gen D7 and D8 are tagged 7: [Lib.D7_con_entry() { ... {offset c1eu: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] [Lib.D8_con_entry() { ... {offset c1ez: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] When switching we now look at the info table only when the tag is 7. For example, if we derive Enum for the type above, the Cmm looks like this: c2Le: _s2Js::P64 = R1; _c2Lq::P64 = _s2Js::P64 & 7; switch [1 .. 7] _c2Lq::P64 { case 1 : goto c2Lk; case 2 : goto c2Ll; case 3 : goto c2Lm; case 4 : goto c2Ln; case 5 : goto c2Lo; case 6 : goto c2Lp; case 7 : goto c2Lj; } // Read info table for tag c2Lj: _c2Lv::I64 = %MO_UU_Conv_W32_W64(I32[I64[_s2Js::P64 & (-8)] - 4]); if (_c2Lv::I64 != 6) goto c2Lu; else goto c2Lt; Generated Cmm sizes do not change too much, but binaries are very slightly larger, due to the fact that the new instructions are longer in encoded form. E.g. previously entry code for D8 above would be 00000000000001c0 <Lib_D8_con_info>: 1c0: 48 ff c3 inc %rbx 1c3: ff 65 00 jmpq *0x0(%rbp) With this patch 00000000000001d0 <Lib_D8_con_info>: 1d0: 48 83 c3 07 add $0x7,%rbx 1d4: ff 65 00 jmpq *0x0(%rbp) This is one byte longer. Secondly, reading info table directly and then switching is shorter _c1co: movq -1(%rbx),%rax movl -4(%rax),%eax // Switch on info table tag jmp *_n1d5(,%rax,8) than doing the same switch, and then for the tag 7 doing another switch: // When tag is 7 _c1ct: andq $-8,%rbx movq (%rbx),%rax movl -4(%rax),%eax // Switch on info table tag ... Some changes of binary sizes in actual programs: - In NoFib the worst case is 0.1% increase in benchmark "parser" (see NoFib results below). All programs get slightly larger. - Stage 2 compiler size does not change. - In "containers" (the library) size of all object files increases 0.0005%. Size of the test program "bitqueue-properties" increases 0.03%. nofib benchmarks kindly provided by Ömer (@osa1): NoFib Results ============= -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.0% 0.0% -0.0% -0.0% -0.0% CSD +0.0% 0.0% 0.0% +0.0% +0.0% FS +0.0% 0.0% 0.0% +0.0% 0.0% S +0.0% 0.0% -0.0% 0.0% 0.0% VS +0.0% 0.0% -0.0% +0.0% +0.0% VSD +0.0% 0.0% -0.0% +0.0% -0.0% VSM +0.0% 0.0% 0.0% 0.0% 0.0% anna +0.0% 0.0% +0.1% -0.9% -0.0% ansi +0.0% 0.0% -0.0% +0.0% +0.0% atom +0.0% 0.0% 0.0% 0.0% 0.0% awards +0.0% 0.0% -0.0% +0.0% 0.0% banner +0.0% 0.0% -0.0% +0.0% 0.0% bernouilli +0.0% 0.0% +0.0% +0.0% +0.0% binary-trees +0.0% 0.0% -0.0% -0.0% -0.0% boyer +0.0% 0.0% +0.0% 0.0% -0.0% boyer2 +0.0% 0.0% +0.0% 0.0% -0.0% bspt +0.0% 0.0% +0.0% +0.0% 0.0% cacheprof +0.0% 0.0% +0.1% -0.8% 0.0% calendar +0.0% 0.0% -0.0% +0.0% -0.0% cichelli +0.0% 0.0% +0.0% 0.0% 0.0% circsim +0.0% 0.0% -0.0% -0.1% -0.0% clausify +0.0% 0.0% +0.0% +0.0% 0.0% comp_lab_zift +0.0% 0.0% +0.0% 0.0% -0.0% compress +0.0% 0.0% +0.0% +0.0% 0.0% compress2 +0.0% 0.0% 0.0% 0.0% 0.0% constraints +0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 +0.0% 0.0% +0.0% 0.0% 0.0% cryptarithm2 +0.0% 0.0% +0.0% -0.0% 0.0% cse +0.0% 0.0% +0.0% +0.0% 0.0% digits-of-e1 +0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 +0.0% 0.0% +0.0% -0.0% -0.0% dom-lt +0.0% 0.0% +0.0% +0.0% 0.0% eliza +0.0% 0.0% -0.0% +0.0% 0.0% event +0.0% 0.0% -0.0% -0.0% -0.0% exact-reals +0.0% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.0% 0.0% -0.0% -0.0% -0.0% expert +0.0% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.0% 0.0% +0.0% 0.0% 0.0% fasta +0.0% 0.0% -0.0% -0.0% -0.0% fem +0.0% 0.0% +0.0% +0.0% +0.0% fft +0.0% 0.0% +0.0% -0.0% -0.0% fft2 +0.0% 0.0% +0.0% +0.0% +0.0% fibheaps +0.0% 0.0% +0.0% +0.0% 0.0% fish +0.0% 0.0% +0.0% +0.0% 0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.0% 0.0% +0.0% -0.0% +0.0% gamteb +0.0% 0.0% +0.0% -0.0% -0.0% gcd +0.0% 0.0% +0.0% +0.0% 0.0% gen_regexps +0.0% 0.0% +0.0% -0.0% -0.0% genfft +0.0% 0.0% -0.0% -0.0% -0.0% gg +0.0% 0.0% 0.0% -0.0% 0.0% grep +0.0% 0.0% +0.0% +0.0% +0.0% hidden +0.0% 0.0% +0.0% -0.0% -0.0% hpg +0.0% 0.0% +0.0% -0.1% -0.0% ida +0.0% 0.0% +0.0% -0.0% -0.0% infer +0.0% 0.0% -0.0% -0.0% -0.0% integer +0.0% 0.0% -0.0% -0.0% -0.0% integrate +0.0% 0.0% 0.0% +0.0% 0.0% k-nucleotide +0.0% 0.0% -0.0% -0.0% -0.0% kahan +0.0% 0.0% -0.0% -0.0% -0.0% knights +0.0% 0.0% +0.0% -0.0% -0.0% lambda +0.0% 0.0% +1.2% -6.1% -0.0% last-piece +0.0% 0.0% +0.0% -0.0% -0.0% lcss +0.0% 0.0% +0.0% -0.0% -0.0% life +0.0% 0.0% +0.0% -0.0% -0.0% lift +0.0% 0.0% +0.0% +0.0% 0.0% linear +0.0% 0.0% +0.0% +0.0% +0.0% listcompr +0.0% 0.0% -0.0% -0.0% -0.0% listcopy +0.0% 0.0% -0.0% -0.0% -0.0% maillist +0.0% 0.0% +0.0% -0.0% -0.0% mandel +0.0% 0.0% +0.0% +0.0% +0.0% mandel2 +0.0% 0.0% +0.0% +0.0% -0.0% mate +0.0% 0.0% +0.0% +0.0% +0.0% minimax +0.0% 0.0% -0.0% +0.0% -0.0% mkhprog +0.0% 0.0% +0.0% +0.0% +0.0% multiplier +0.0% 0.0% 0.0% +0.0% -0.0% n-body +0.0% 0.0% +0.0% -0.0% -0.0% nucleic2 +0.0% 0.0% +0.0% +0.0% -0.0% para +0.0% 0.0% +0.0% +0.0% +0.0% paraffins +0.0% 0.0% +0.0% +0.0% +0.0% parser +0.1% 0.0% +0.4% -1.7% -0.0% parstof +0.0% 0.0% -0.0% -0.0% -0.0% pic +0.0% 0.0% +0.0% 0.0% -0.0% pidigits +0.0% 0.0% -0.0% -0.0% -0.0% power +0.0% 0.0% +0.0% -0.0% -0.0% pretty +0.0% 0.0% +0.0% +0.0% +0.0% primes +0.0% 0.0% +0.0% 0.0% 0.0% primetest +0.0% 0.0% +0.0% +0.0% +0.0% prolog +0.0% 0.0% +0.0% +0.0% +0.0% puzzle +0.0% 0.0% +0.0% +0.0% +0.0% queens +0.0% 0.0% 0.0% +0.0% +0.0% reptile +0.0% 0.0% +0.0% +0.0% 0.0% reverse-complem +0.0% 0.0% -0.0% -0.0% -0.0% rewrite +0.0% 0.0% +0.0% 0.0% -0.0% rfib +0.0% 0.0% +0.0% +0.0% +0.0% rsa +0.0% 0.0% +0.0% +0.0% +0.0% scc +0.0% 0.0% +0.0% +0.0% +0.0% sched +0.0% 0.0% +0.0% +0.0% +0.0% scs +0.0% 0.0% +0.0% +0.0% 0.0% simple +0.0% 0.0% +0.0% +0.0% +0.0% solid +0.0% 0.0% +0.0% +0.0% 0.0% sorting +0.0% 0.0% +0.0% -0.0% 0.0% spectral-norm +0.0% 0.0% -0.0% -0.0% -0.0% sphere +0.0% 0.0% +0.0% -1.0% 0.0% symalg +0.0% 0.0% +0.0% +0.0% +0.0% tak +0.0% 0.0% +0.0% +0.0% +0.0% transform +0.0% 0.0% +0.4% -1.3% +0.0% treejoin +0.0% 0.0% +0.0% -0.0% 0.0% typecheck +0.0% 0.0% -0.0% +0.0% 0.0% veritas +0.0% 0.0% +0.0% -0.1% +0.0% wang +0.0% 0.0% +0.0% +0.0% +0.0% wave4main +0.0% 0.0% +0.0% 0.0% -0.0% wheel-sieve1 +0.0% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.0% 0.0% +0.0% +0.0% 0.0% x2n1 +0.0% 0.0% +0.0% +0.0% 0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -6.1% -0.0% Max +0.1% 0.0% +1.2% +0.0% +0.0% Geometric Mean +0.0% -0.0% +0.0% -0.1% -0.0% NoFib GC Results ================ -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim +0.0% 0.0% -0.0% -0.0% -0.0% constraints +0.0% 0.0% -0.0% 0.0% -0.0% fibheaps +0.0% 0.0% 0.0% -0.0% -0.0% fulsom +0.0% 0.0% 0.0% -0.6% -0.0% gc_bench +0.0% 0.0% 0.0% 0.0% -0.0% hash +0.0% 0.0% -0.0% -0.0% -0.0% lcss +0.0% 0.0% 0.0% -0.0% 0.0% mutstore1 +0.0% 0.0% 0.0% -0.0% -0.0% mutstore2 +0.0% 0.0% +0.0% -0.0% -0.0% power +0.0% 0.0% -0.0% 0.0% -0.0% spellcheck +0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.6% -0.0% Max +0.0% 0.0% +0.0% 0.0% 0.0% Geometric Mean +0.0% +0.0% +0.0% -0.1% +0.0% Fixes #14373 These performance regressions appear to be a fluke in CI. See the discussion in !1742 for details. Metric Increase: T6048 T12234 T12425 Naperian T12150 T5837 T13035 - - - - - ee07421f by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Work in progress on coercionLKind, coercionRKind This is a preliminary patch for #17515 - - - - - 0a4ca9eb by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Split up coercionKind This patch implements the idea in #17515, splitting `coercionKind` into: * `coercion{Left,Right}Kind`, which computes the left/right side of the pair * `coercionKind`, which computes the pair of coercible types This is reduces allocation since we frequently only need only one side of the pair. Specifically, we see the following improvements on x86-64 Debian 9: | test | new | old | relative chg. | | :------- | ---------: | ------------: | ------------: | | T5030 | 695537752 | 747641152.0 | -6.97% | | T5321Fun | 449315744 | 474009040.0 | -5.21% | | T9872a | 2611071400 | 2645040952.0 | -1.28% | | T9872c | 2957097904 | 2994260264.0 | -1.24% | | T12227 | 773435072 | 812367768.0 | -4.79% | | T12545 | 3142687224 | 3215714752.0 | -2.27% | | T14683 | 9392407664 | 9824775000.0 | -4.40% | Metric Decrease: T12545 T9872a T14683 T5030 T12227 T9872c T5321Fun T9872b - - - - - d46a72e1 by Gabor Greif at 2019-12-09T12:05:15-05:00 Fix comment typos The below is only necessary to fix the CI perf fluke that happened in 9897e8c8ef0b19a9571ef97a1d9bb050c1ee9121: ------------------------- Metric Decrease: T5837 T6048 T9020 T12425 T12234 T13035 T12150 Naperian ------------------------- - - - - - e3bba7e4 by Micha Wiedenmann at 2019-12-10T19:52:44-05:00 users guide: Motivation of DefaultSignatures - - - - - 843ceb38 by Ben Gamari at 2019-12-10T19:53:54-05:00 rts: Add a long form flag to enable the non-moving GC The old flag, `-xn`, was quite cryptic. Here we add `--nonmoving-gc` in addition. - - - - - 921d3238 by Ryan Scott at 2019-12-10T19:54:34-05:00 Ignore unary constraint tuples during typechecking (#17511) We deliberately avoid defining a magical `Unit%` class, for reasons that I have expounded upon in the newly added `Note [Ignore unary constraint tuples]` in `TcHsType`. However, a sneaky user could try to insert `Unit%` into their program by way of Template Haskell, leading to the interface-file error observed in #17511. To avoid this, any time we encounter a unary constraint tuple during typechecking, we drop the surrounding constraint tuple application. This is safe to do since `Unit% a` and `a` would be semantically equivalent (unlike other forms of unary tuples). Fixes #17511. - - - - - 436ec9f3 by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 2f6b434f by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 7a5a6e07 by Ben Gamari at 2019-12-10T19:56:25-05:00 base: Fix incorrect @since in GHC.Natural Fixes #17547. - - - - - 2bbfaf8a by Ben Gamari at 2019-12-10T19:57:01-05:00 hadrian: AArch64 supports the GHCi interpreter and SMP I'm not sure how this was omitted from the list of supported architectures. - - - - - 8f1ceb67 by John Ericson at 2019-12-10T19:57:39-05:00 Move Int# section of primops.txt.pp This matches the organization of the fixed-sized ones, and keeps each Int* next to its corresponding Word*. - - - - - 7a823b0f by John Ericson at 2019-12-10T19:57:39-05:00 Move Int64# and Word64# sections of primops.txt.pp This way it is next to the other fixed-sized ones. - - - - - 8dd9929a by Ben Gamari at 2019-12-10T19:58:19-05:00 testsuite: Add (broken) test for #17510 - - - - - 6e47a76a by Ben Gamari at 2019-12-10T19:58:59-05:00 Re-layout validate script This script was previously a whitespace nightmare. - - - - - f80c4a66 by Crazycolorz5 at 2019-12-11T14:12:17-05:00 rts: Specialize hashing at call site rather than in struct. Separate word and string hash tables on the type level, and do not store the hashing function. Thus when a different hash function is desire it is provided upon accessing the table. This is worst case the same as before the change, and in the majority of cases is better. Also mark the functions for aggressive inlining to improve performance. {F1686506} Reviewers: bgamari, erikd, simonmar Subscribers: rwbarton, thomie, carter GHC Trac Issues: #13165 Differential Revision: https://phabricator.haskell.org/D4889 - - - - - 2d1b9619 by Richard Eisenberg at 2019-12-11T14:12:55-05:00 Warn on inferred polymorphic recursion Silly users sometimes try to use visible dependent quantification and polymorphic recursion without a CUSK or SAK. This causes unexpected errors. So we now adjust expectations with a bit of helpful messaging. Closes #17541 and closes #17131. test cases: dependent/should_fail/T{17541{,b},17131} - - - - - 4dde485e by Oleg Grenrus at 2019-12-12T02:24:46-05:00 Add --show-unit-ids flag to ghc-pkg I only added it into --simple-output and ghc-pkg check output; there are probably other places where it can be adopted. - - - - - e6e1ec08 by Ben Gamari at 2019-12-12T02:25:33-05:00 testsuite: Simplify and clarify performance test baseline search The previous implementation was extremely complicated, seemingly to allow the local and CI namespaces to be searched incrementally. However, it's quite unclear why this is needed and moreover the implementation seems to have had quadratic runtime cost in the search depth(!). - - - - - 29c4609c by Ben Gamari at 2019-12-12T02:26:19-05:00 testsuite: Add test for #17549 - - - - - 9f0ee253 by Ben Gamari at 2019-12-12T02:26:56-05:00 gitlab-ci: Move -dwarf and -debug jobs to full-build stage This sacrifices some precision in favor of improving parallelism. - - - - - 7179b968 by Ben Gamari at 2019-12-12T02:27:34-05:00 Revert "rts: Drop redundant flags for libffi" This seems to have regressed builds using `--with-system-libffi` (#17520). This reverts commit 3ce18700f80a12c48a029b49c6201ad2410071bb. - - - - - cc7d5650 by Oleg Grenrus at 2019-12-16T10:20:56+02:00 Having no shake upper bound is irresposible Given that shake is far from "done" API wise, and is central component to the build system. - - - - - 9431f905 by Oleg Grenrus at 2019-12-16T10:55:50+02:00 Add index-state to hadrian/cabal.project Then one is freer to omit upper bounds, as we won't pick any new entries on Hackage while building hadrian itself. - - - - - 3e17a866 by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Remove dataConSig As suggested in #17291 - - - - - 75355fde by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Use "OrCoVar" functions less As described in #17291, we'd like to separate coercions and expressions in a more robust fashion. This is a small step in this direction. - `mkLocalId` now panicks on a covar. Calls where this was not the case were changed to `mkLocalIdOrCoVar`. - Don't use "OrCoVar" functions in places where we know the type is not a coercion. - - - - - f9686e13 by Richard Eisenberg at 2019-12-16T19:32:21-05:00 Do more validity checks for quantified constraints Close #17583. Test case: typecheck/should_fail/T17563 - - - - - af763765 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Fix Windows artifact collection Variable interpolation in gitlab-ci.yml apparently doesn't work. Sigh. - - - - - e6d4b902 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Debian 10 - - - - - 8ba650e9 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Allow debian 8 build to fail The python release shipped with deb8 (3.3) is too old for our testsuite driver. - - - - - ac25a3f6 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Alpine - - - - - cc628088 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Another approach for xz detection - - - - - 37d788ab by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Re-add release-x86_64-deb9 job Also eliminate some redundancy. - - - - - f8279138 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Drop redundant release-x86_64-linux-deb9 job - - - - - 8148ff06 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark cgrun057 as broken on ARMv7 Due to #17554. It's very surprising that this only occurs on ARMv7 but this is the only place I've seen this failure thusfar. - - - - - 85e5696d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark prog001 as fragile on ARMv7 Due to #17555. - - - - - a5f0aab0 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T10272 as broken on ARMv7 Due to #17556. - - - - - 1e6827c6 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T13825-debugger as broken on ARMv7 Due to #17557. - - - - - 7cef0b7d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T14028 as broken on ARMv7 Due to #17558. - - - - - 6ea4eb4b by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Make ghc_built_by_llvm check more precise Previously it would hackily look at the flavour name to determine whether LLVM was used to build stage2 ghc. However, this didn't work at all with Hadrian and would miss cases like ARM where we use the LLVM backend by default. See #16087 for the motivation for why ghc_built_by_llvm is needed at all. This should catch one of the ARMv7 failures described in #17555. - - - - - c3e82bf7 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T5435_* tests as broken on ARM `T5435_v_asm_a`, `T5435_v_asm_b`, and `T5435_v_gcc` all fail on ARMv7. See #17559. - - - - - eb2aa851 by Ben Gamari at 2019-12-17T07:24:40-05:00 gitlab-ci: Don't allow armv7 jobs to fail - - - - - efc92216 by Ben Gamari at 2019-12-17T07:24:40-05:00 Revert "testsuite: Mark cgrun057 as broken on ARMv7" This reverts commit 6cfc47ec8a478e1751cb3e7338954da1853c3996. - - - - - 1d2bb9eb by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark print002 as fragile on ARM Due to #17557. Also accepting spurious performance change. Metric Decrease: T1969 - - - - - 41f4e4fb by Josh Meredith at 2019-12-17T07:25:17-05:00 Fix ambiguous occurence error when building Hadrian - - - - - 4374983a by Josh Meredith at 2019-12-17T07:25:17-05:00 Rename SphinxMode constructors - - - - - a8f7ecd5 by Josh Meredith at 2019-12-17T07:25:17-05:00 Use *Mode suffix instead of *M - - - - - 58655b9d by Sylvain Henry at 2019-12-18T13:43:37+01:00 Add GHC-API logging hooks * Add 'dumpAction' hook to DynFlags. It allows GHC API users to catch dumped intermediate codes and information. The format of the dump (Core, Stg, raw text, etc.) is now reported allowing easier automatic handling. * Add 'traceAction' hook to DynFlags. Some dumps go through the trace mechanism (for instance unfoldings that have been considered for inlining). This is problematic because: 1) dumps aren't written into files even with -ddump-to-file on 2) dumps are written on stdout even with GHC API 3) in this specific case, dumping depends on unsafe globally stored DynFlags which is bad for GHC API users We introduce 'traceAction' hook which allows GHC API to catch those traces and to avoid using globally stored DynFlags. * Avoid dumping empty logs via dumpAction/traceAction (but still write empty files to keep the existing behavior) - - - - - fad866e0 by Moritz Kiefer at 2019-12-19T11:15:39-05:00 Avoid race condition in hDuplicateTo In our codebase we have some code along the lines of ``` newStdout <- hDuplicate stdout stderr `hDuplicateTo` stdout ``` to avoid stray `putStrLn`s from corrupting a protocol (LSP) that is run over stdout. On CI we have seen a bunch of issues where `dup2` returned `EBUSY` so this fails with `ResourceExhausted` in Haskell. I’ve spent some time looking at the docs for `dup2` and the code in `base` and afaict the following race condition is being triggered here: 1. The user calls `hDuplicateTo stderr stdout`. 2. `hDuplicateTo` calls `hClose_help stdout_`, this closes the file handle for stdout. 3. The file handle for stdout is now free, so another thread allocating a file might get stdout. 4. If `dup2` is called while `stdout` (now pointing to something else) is half-open, it returns EBUSY. I think there might actually be an even worse case where `dup2` is run after FD 1 is fully open again. In that case, you will end up not just redirecting the original stdout to stderr but also the whatever resulted in that file handle being allocated. As far as I can tell, `dup2` takes care of closing the file handle itself so there is no reason to do this in `hDuplicateTo`. So this PR replaces the call to `hClose_help` by the only part of `hClose_help` that we actually care about, namely, `flushWriteBuffer`. I tested this on our codebase fairly extensively and haven’t been able to reproduce the issue with this patch. - - - - - 0c114c65 by Sylvain Henry at 2019-12-19T11:16:17-05:00 Handle large ARR_WORDS in heap census (fix #17572) We can do a heap census with a non-profiling RTS. With a non-profiling RTS we don't zero superfluous bytes of shrunk arrays hence a need to handle the case specifically to avoid a crash. Revert part of a586b33f8e8ad60b5c5ef3501c89e9b71794bbed - - - - - 1a0d1a65 by John Ericson at 2019-12-20T10:50:22-05:00 Deduplicate copied monad failure handler code - - - - - 70e56b27 by Ryan Scott at 2019-12-20T10:50:57-05:00 lookupBindGroupOcc: recommend names in the same namespace (#17593) Previously, `lookupBindGroupOcc`'s error message would recommend all similar names in scope, regardless of whether they were type constructors, data constructors, or functions, leading to the confusion witnessed in #17593. This is easily fixed by only recommending names in the same namespace, using the `nameSpacesRelated` function. Fixes #17593. - - - - - 3c12355e by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN Include header file `ghcautoconf.h` where the CPP macro `WORDS_BIGENDIAN` is defined. This finally fixes #17337 (in conjunction with commit 6c59cc71dc). - - - - - 11f8eef5 by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 fixup! Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN - - - - - 40327b03 by Sylvain Henry at 2019-12-24T01:04:24-05:00 Remove outdated comment - - - - - aeea92ef by Sylvain Henry at 2019-12-25T19:23:54-05:00 Switch to ReadTheDocs theme for the user-guide - - - - - 26493eab by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix copy-paste error in comment - - - - - 776df719 by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix comment about minimal gcc version to be consistent what FP_GCC_VERSION requires - - - - - 3b17114d by Ömer Sinan Ağacan at 2019-12-26T14:09:11-05:00 Minor refactor in ghc.cabal.in: - Remove outdated comments - Move cutils.c from parser to cbits - Remove unused cutils.h - - - - - 334290b6 by Ryan Scott at 2019-12-26T14:09:48-05:00 Replace panic/notHandled with noExtCon in DsMeta There are many spots in `DsMeta` where `panic` or `notHandled` is used after pattern-matching on a TTG extension constructor. This is overkill, however, as using `noExtCon` would work just as well. This patch switches out these panics for `noExtCon`. - - - - - 68252aa3 by Ben Gamari at 2019-12-27T15:11:38-05:00 testsuite: Skip T17499 when built against integer-simple Since it routinely times out in CI. - - - - - 0c51aeeb by Gabor Greif at 2019-12-27T15:12:17-05:00 suppress popup dialog about missing Xcode at configure tested with `bash` and `zsh`. - - - - - 8d76bcc2 by Gabor Greif at 2019-12-27T15:12:17-05:00 while at it rename XCode to the official Xcode - - - - - 47a68205 by Ben Gamari at 2019-12-27T15:12:55-05:00 testsuite: Mark cgrun057 as fragile on ARM As reported in #17554. Only marking on ARM for now although there is evidence to suggest that the issue may occur on other platforms as well. - - - - - d03dec8f by Gabor Greif at 2019-12-27T15:13:32-05:00 use shell variable CcLlvmBackend for test Previously we used `AC_DEFINE`d variable `CC_LLVM_BACKEND` which has an empty shell expansion. - - - - - 2528e684 by Ben Gamari at 2019-12-30T06:51:32-05:00 driver: Include debug level in the recompilation check hash Fixes #17586. - - - - - f14bb50b by Ben Gamari at 2019-12-30T06:52:09-05:00 rts: Ensure that nonmoving gc isn't used with profiling - - - - - b426de37 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Ensure that entry labels don't have predecessors The LLVM IR forbids the entry label of a procedure from having any predecessors. In the case of a simple looping function the LLVM code generator broke this invariant, as noted in #17589. Fix this by moving the function prologue to its own basic block, as suggested by @kavon in #11649. Fixes #11649 and #17589. - - - - - 613f7265 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Drop old fix for #11649 This was a hack which is no longer necessary now since we introduce a dedicated entry block for each procedure. - - - - - fdeffa5e by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Error on invalid --numa flags Previously things like `+RTS --numa-debug` would enable NUMA support, despite being an invalid flag. - - - - - 9ce3ba68 by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Fix --debug-numa mode under Docker As noted in #17606, Docker disallows the get_mempolicy syscall by default. This caused numerous tests to fail under CI in the `debug_numa` way. Avoid this by disabling the NUMA probing logic when --debug-numa is in use, instead setting n_numa_nodes in RtsFlags.c. Fixes #17606. - - - - - 5baa2a43 by Ben Gamari at 2019-12-30T06:54:01-05:00 testsuite: Disable derefnull when built with LLVM LLVM does not guarantee any particular semantics when dereferencing null pointers. Consequently, this test actually passes when built with the LLVM backend. - - - - - bd544d3d by Ben Gamari at 2019-12-30T06:54:38-05:00 hadrian: Track hash of Cabal Setup builder arguments Lest we fail to rebuild when they change. Fixes #17611. - - - - - 6e2c495e by Ben Gamari at 2019-12-30T06:55:19-05:00 TcIface: Fix inverted logic in typechecking of source ticks Previously we would throw away source ticks when the debug level was non-zero. This is precisely the opposite of what was intended. Fixes #17616. Metric Decrease: T13056 T9020 T9961 T12425 - - - - - 7fad387d by Ben Gamari at 2019-12-30T06:55:55-05:00 perf_notes: Add --zero-y argument This makes it easier to see the true magnitude of fluctuations. Also do some house-keeping in the argument parsing department. - - - - - 0d42b287 by Ben Gamari at 2019-12-30T06:55:55-05:00 testsuite: Enlarge acceptance window for T1969 As noted in #17624, it's quite unstable, especially, for some reason, on i386 and armv7 (something about 32-bit platforms perhaps?). Metric Increase: T1969 - - - - - eb608235 by Sylvain Henry at 2019-12-31T14:22:32-05:00 Module hierarchy (#13009): Stg - - - - - d710fd66 by Vladislav Zavialov at 2019-12-31T14:23:10-05:00 Testsuite: update some Haddock tests Fixed tests: * haddockA039: added to all.T * haddockE004: replaced with T17561 (marked as expect_broken) New tests: * haddockA040: deriving clause for a data instance * haddockA041: haddock and CPP #include - - - - - 859ebdd4 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add "-Iw" RTS flag for minimum wait between idle GCs (#11134) - - - - - dd4b6551 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add additional Note explaining the -Iw flag - - - - - c4279ff1 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Fix some sloppy indentation - - - - - b84c09d5 by Ömer Sinan Ağacan at 2019-12-31T23:45:19-05:00 Tweak Cmm dumps to avoid generating sections for empty groups When dumping Cmm groups check if the group is empty, to avoid generating empty sections in dump files like ==================== Output Cmm ==================== [] Also fixes a few bad indentation in the code around changes. - - - - - b2e0323f by Gabor Greif at 2020-01-03T21:22:36-05:00 Simplify mrStr - - - - - 3c9dc06b by Brian Wignall at 2020-01-04T15:55:06-05:00 Fix typos, via a Levenshtein-style corrector - - - - - d561c8f6 by Sylvain Henry at 2020-01-04T15:55:46-05:00 Add Cmm related hooks * stgToCmm hook * cmmToRawCmm hook These hooks are used by Asterius and could be useful to other clients of the GHC API. It increases the Parser dependencies (test CountParserDeps) to 184. It's still less than 200 which was the initial request (cf https://mail.haskell.org/pipermail/ghc-devs/2019-September/018122.html) so I think it's ok to merge this. - - - - - ae6b6276 by Oleg Grenrus at 2020-01-04T15:56:22-05:00 Update to Cabal submodule to v3.2.0.0-alpha3 Metric Increase: haddock.Cabal - - - - - 073f7cfd by Vladislav Zavialov at 2020-01-04T15:56:59-05:00 Add lexerDbg to dump the tokens fed to the parser This a small utility function that comes in handy when debugging the lexer and the parser. - - - - - 558d4d4a by Sylvain Henry at 2020-01-04T15:57:38-05:00 Split integerGmpInternals test in several parts This is to prepare for ghc-bignum which implements some but not all of gmp functions. - - - - - 4056b966 by Ben Gamari at 2020-01-04T15:58:15-05:00 testsuite: Mark cgrun057 as fragile on all platforms I have seen this fail both on x86-64/Debian 9 and armv7/Debian 9 See #17554. - - - - - 5ffea0c6 by Tamar Christina at 2020-01-06T18:38:37-05:00 Fix overflow. - - - - - 99a9f51b by Sylvain Henry at 2020-01-06T18:39:22-05:00 Module hierarchy: Iface (cf #13009) - - - - - 7aa4a061 by Ben Gamari at 2020-01-07T13:11:48-05:00 configure: Only check GCC version if CC is GCC Also refactor FP_GCC_EXTRA_FLAGS in a few ways: * We no longer support compilers which lack support for -fno-builtin and -fwrapv so remove the condition on GccVersion * These flags are only necessary when using the via-C backend so make them conditional on Unregisterised. Fixes #15742. - - - - - 0805ed7e by John Ericson at 2020-01-07T13:12:25-05:00 Use non-empty lists to remove partiality in matching code - - - - - 7844f3a8 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Mark T17073 as broken on Windows Due to #17607. - - - - - acf40cae by Ben Gamari at 2020-01-07T13:13:02-05:00 gitlab-ci: Disallow Windows from failing - - - - - 34bc02c7 by Ben Gamari at 2020-01-07T13:13:02-05:00 configure: Find Python3 for testsuite In addition, we prefer the Mingw64 Python distribution on Windows due to #17483. - - - - - e35fe8d5 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Fix Windows platform test Previously we used platform.system() and while this worked fine (e.g. returned `Windows`, as expected) locally under both msys and MingW64 Python distributions, it inexplicably returned `MINGW64_NT-10.0` under MingW64 Python on CI. It seems os.name is more reliable so we now use that instead.. - - - - - 48ef6217 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Rename push-test-metrics.sh to test-metrics.sh Refactoring to follow. - - - - - 2234fa92 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Pull test metrics before running testsuite Otherwise the testsuite driver may not have an up-to-date baseline. - - - - - 1ca9adbc by Sylvain Henry at 2020-01-07T13:14:18-05:00 Remove `parallel` check from configure.ac `parallel` is no longer a submodule since 3cb063c805ec841ca33b8371ef8aba9329221b6c - - - - - b69a3460 by Ryan Scott at 2020-01-07T13:14:57-05:00 Monomorphize HsModule to GhcPs (#17642) Analyzing the call sites for `HsModule` reveals that it is only ever used with parsed code (i.e., `GhcPs`). This simplifies `HsModule` by concretizing its `pass` parameter to always be `GhcPs`. Fixes #17642. - - - - - d491a679 by Sylvain Henry at 2020-01-08T06:16:31-05:00 Module hierarchy: Renamer (cf #13009) - - - - - d589410f by Ben Gamari at 2020-01-08T06:17:09-05:00 Bump haskeline submodule to 0.8.0.1 (cherry picked from commit feb3b955402d53c3875dd7a9a39f322827e5bd69) - - - - - 923a1272 by Ryan Scott at 2020-01-08T06:17:47-05:00 Print Core type applications with no whitespace after @ (#17643) This brings the pretty-printer for Core in line with how visible type applications are normally printed: namely, with no whitespace after the `@` character (i.e., `f @a` instead of `f @ a`). While I'm in town, I also give the same treatment to type abstractions (i.e., `\(@a)` instead of `\(@ a)`) and coercion applications (i.e., `f @~x` instead of `f @~ x`). Fixes #17643. - - - - - 49f83a0d by Adam Sandberg Eriksson at 2020-01-12T21:28:09-05:00 improve docs for HeaderInfo.getImports [skip ci] - - - - - 9129210f by Matthew Pickering at 2020-01-12T21:28:47-05:00 Overloaded Quotation Brackets (#246) This patch implements overloaded quotation brackets which generalise the desugaring of all quotation forms in terms of a new minimal interface. The main change is that a quotation, for example, [e| 5 |], will now have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass contains a single method for generating new names which is used when desugaring binding structures. The return type of functions from the `Lift` type class, `lift` and `liftTyped` have been restricted to `forall m . Quote m => m Exp` rather than returning a result in a Q monad. More details about the feature can be read in the GHC proposal. https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst - - - - - 350e2b78 by Richard Eisenberg at 2020-01-12T21:29:27-05:00 Don't zap to Any; error instead This changes GHC's treatment of so-called Naughty Quantification Candidates to issue errors, instead of zapping to Any. Close #16775. No new test cases, because existing ones cover this well. - - - - - 0b5ddc7f by Brian Wignall at 2020-01-12T21:30:08-05:00 Fix more typos, via an improved Levenshtein-style corrector - - - - - f732dbec by Ben Gamari at 2020-01-12T21:30:49-05:00 gitlab-ci: Retain bindists used by head.hackage for longer Previously we would keep them for two weeks. However, on the stable branches two weeks can easily elapse with no pushes. - - - - - c8636da5 by Sylvain Henry at 2020-01-12T21:31:30-05:00 Fix LANG=C for readelf invocation in T14999 The test fails when used with LANG=fr_FR.UTF-8 - - - - - 077a88de by Jean-Baptiste Mazon at 2020-01-12T21:32:08-05:00 users-guide/debug-info: typo “behivior” - - - - - 61916c5d by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Add comments about TH levels - - - - - 1fd766ca by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Comments about constraint floating - - - - - de01427e by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Minor refactor around quantified constraints This patch clarifies a dark corner of quantified constraints. * See Note [Yukky eq_sel for a HoleDest] in TcSMonad * Minor refactor, breaking out new function TcInteract.doTopReactEqPred - - - - - 30be3bf1 by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Comments in TcHsType - - - - - c5977d4d by Sebastian Graf at 2020-01-16T05:58:58-05:00 Better documentation for mkEtaWW [skip ci] So that hopefully I understand it faster next time. Also got rid of the confusing `orig_expr`, which makes the call site in `etaExpand` look out of sync with the passed `n` (which is not the original `n`). - - - - - 22c0bdc3 by John Ericson at 2020-01-16T05:59:37-05:00 Handle TagToEnum in the same big case as the other primops Before, it was a panic because it was handled above. But there must have been an error in my reasoning (another caller?) because #17442 reported the panic was hit. But, rather than figuring out what happened, I can just make it impossible by construction. By adding just a bit more bureaucracy in the return types, I can handle TagToEnum in the same case as all the others, so the big case is is now total, and the panic is removed. Fixes #17442 - - - - - ee5d63f4 by John Ericson at 2020-01-16T05:59:37-05:00 Get rid of OpDest `OpDest` was basically a defunctionalization. Just turn the code that cased on it into those functions, and call them directly. - - - - - 1ff55226 by John Ericson at 2020-01-16T06:00:16-05:00 Remove special case case of bool during STG -> C-- Allow removing the no longer needed cgPrimOp, getting rid of a small a small layer violation too. Change which made the special case no longer needed was #6135 / 6579a6c73082387f82b994305011f011d9d8382b, which dates back to 2013, making me feel better. - - - - - f416fe64 by Adam Wespiser at 2020-01-16T06:00:53-05:00 replace dead html link (fixes #17661) - - - - - f6bf2ce8 by Sebastian Graf at 2020-01-16T06:01:32-05:00 Revert "`exprOkForSpeculation` for Note [IO hack in the demand analyser]" This reverts commit ce64b397777408731c6dd3f5c55ea8415f9f565b on the grounds of the regression it would introduce in a couple of packages. Fixes #17653. Also undoes a slight metric increase in #13701 introduced by that commit that we didn't see prior to !1983. Metric Decrease: T13701 - - - - - a71323ff by Ben Gamari at 2020-01-17T08:43:16-05:00 gitlab-ci: Don't FORCE_SYMLINKS on Windows Not all runners have symlink permissions enabled. - - - - - 0499e3bc by Ömer Sinan Ağacan at 2020-01-20T15:31:33-05:00 Fix +RTS -Z flag documentation Stack squeezing is done on context switch, not on GC or stack overflow. Fix the documentation. Fixes #17685 [ci skip] - - - - - a661df91 by Ömer Sinan Ağacan at 2020-01-20T15:32:13-05:00 Document Stg.FVs module Fixes #17662 [ci skip] - - - - - db24e480 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Don't trash STG registers Fixes #13904. - - - - - f3d7fdb3 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix typo in readnone attribute - - - - - 442751c6 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Add lower-expect to the -O0 optimisation set @kavon says that this will improve block layout for stack checks. - - - - - e90ecc93 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix #14251 Fixes the calling convention for functions passing raw SSE-register values by adding padding as needed to get the values in the right registers. This problem cropped up when some args were unused an dropped from the live list. This folds together 2e23e1c7de01c92b038e55ce53d11bf9db993dd4 and 73273be476a8cc6c13368660b042b3b0614fd928 previously from @kavon. Metric Increase: T12707 ManyConstructors - - - - - 66e511a4 by Ben Gamari at 2020-01-20T15:33:28-05:00 testsuite: Preserve more information in framework failures Namely print the entire exception in hopes that this will help track down #17649. - - - - - b62b8cea by Ömer Sinan Ağacan at 2020-01-20T15:34:06-05:00 Remove deprecated -smp flag It was deprecated in 2012 with 46258b40 - - - - - 0c04a86a by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Reenable submodule linter - - - - - 2bfabd22 by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Allow submodule cleaning to fail on Windows Currently CI is inexplicably failing with ``` $ git submodule foreach git clean -xdf fatal: not a git repository: libffi-tarballs/../.git/modules/libffi-tarballs ``` I have no idea how this working tree got into such a state but we do need to fail more gracefully when it happens. Consequently, we allow the cleaning step to fail. - - - - - 14bced99 by Xavier Denis at 2020-01-20T15:35:21-05:00 Put the docs for :instances in alphabetical position - - - - - 7e0bb82b by Ben Gamari at 2020-01-20T15:35:57-05:00 Add missing Note [Improvement from Ground Wanteds] Closes #17659. - - - - - 17e43a7c by Ben Gamari at 2020-01-20T15:36:32-05:00 unregisterised: Fix declaration for stg_NO_FINALIZER Previously it had a redundant _entry suffix. We never noticed this previously presumably because we never generated references to it (however hard to believe this may be). However, it did start failing in !1304. - - - - - 3dae006f by PHO at 2020-01-20T15:37:08-05:00 Avoid ./configure failure on NetBSD - - - - - 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 50276c01 by Ben Gamari at 2020-04-08T10:44:30+03:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 17 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - + .gitlab/linters/check-changelogs.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/push-test-metrics.sh - + .gitlab/test-metrics.sh - − .gitlab/win32-init.sh - .gitmodules - CODEOWNERS - HACKING.md - aclocal.m4 - boot - + compiler/GHC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e58e7ab3150697daf1e424fee00ad6879020c2e0...50276c01912a28eace285b7dd5f00572674ea9b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e58e7ab3150697daf1e424fee00ad6879020c2e0...50276c01912a28eace285b7dd5f00572674ea9b5 You're receiving 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 8 08:18:02 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 08 Apr 2020 04:18:02 -0400 Subject: [Git][ghc/ghc][wip/T17923] 8 commits: Don't override proc CafInfos in ticky builds Message-ID: <5e8d88ba8a152_61673f8199536d94360412a@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17923 at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 582ee21f by Simon Peyton Jones at 2020-04-08T09:17:24+01:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.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/92904edf42b8bf154e3e6ab0680bb17d31d0d71b...582ee21f82eadac2d3e92d07f4f0ac4e241e31d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92904edf42b8bf154e3e6ab0680bb17d31d0d71b...582ee21f82eadac2d3e92d07f4f0ac4e241e31d3 You're receiving 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 8 09:34:06 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 08 Apr 2020 05:34:06 -0400 Subject: [Git][ghc/ghc][wip/T17917] 19 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e8d9a8e81441_616713503ee03638212@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 6d9fd7cd by Simon Peyton Jones at 2020-04-08T09:22:08+01:00 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. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9a18e3220ca0ab162a9f1047479f83fb7a327bfa...6d9fd7cd87afa68586da31973fd49036aa566d39 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9a18e3220ca0ab162a9f1047479f83fb7a327bfa...6d9fd7cd87afa68586da31973fd49036aa566d39 You're receiving 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 8 09:48:09 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 08 Apr 2020 05:48:09 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Fix the perf regression in T12227/T12545 Message-ID: <5e8d9dd9dda8_61677c82e0c36459b8@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: fcd81dbc by Sebastian Graf at 2020-04-08T11:47:45+02:00 Fix the perf regression in T12227/T12545 But now T9233 fails because we are doing more work. Temporarily marking as accepted increase. Metric Increase: T9233 Metric Decrease: hie002 - - - - - 4 changed files: - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -27,6 +27,7 @@ import Data.List ( mapAccumL ) import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Core.Arity ( typeArity ) import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type @@ -152,7 +153,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +411,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -510,27 +511,63 @@ dmdTransform :: AnalEnv -- The strictness environment -- this function plus demand on its free variables dmdTransform env var dmd - | isDataConWorkId var -- Data constructor + -- Data constructors + | isDataConWorkId var = dmdTransformDataConSig (idArity var) (idStrictness var) dmd - + -- Dictionary component selectors | gopt Opt_DmdTxDictSel (ae_dflags env), - Just _ <- isClassOpId_maybe var -- Dictionary component selector + Just _ <- isClassOpId_maybe var = dmdTransformDictSelSig (idStrictness var) dmd - - | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + -- Imported functions + | isGlobalId var + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:import" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res - - | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing + -- Top-level or local let-bound thing for which we use LetDown ('useLetUp'). + -- In that case, we have a strictness signature to unleash in our AnalEnv. + | Just (sig, top_lvl) <- lookupSigEnv env var , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:LetDown" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl - then fn_ty -- Don't record top level things + then fn_ty -- Don't record demand on top-level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) - - | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + -- Everything else: + -- * Local let binders for which we use LetUp (cf. 'useLetUp') + -- * Lambda binders + -- * Case and constructor field binders + | let sig = mkConservativeSig env (idType var) + , let res = dmdTransformSig sig dmd + = -- pprTrace "dmdTransform:Other" (vcat [ppr var, ppr sig, ppr dmd, ppr res]) $ + addVarDmd res var (mkOnceUsedDmd dmd) + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig env (idType var) + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> Type -> StrictSig +mkConservativeSig env ty + -- Binders of unlifted types can't throw anything. This special case isn't + -- handled well by forcesRealWorld, which focuses on case scrutinees. + | unlifted = emptySig conDiv + -- no point in retaining cleared_sig when it's just Top + | no_change = topSig + | otherwise = cleared_sig + where + unlifted = isLiftedType_maybe ty == Just False + fam_envs = ae_fam_envs env + -- This is isomorphic to topSig. But this one has the right number of + -- arguments and will possibly have conDiv after the call to + -- tryClearPreciseException! + pessimistic_sig = StrictSig $ DmdType emptyVarEnv args topDiv + args = replicate (length (typeArity ty)) topDmd + -- In contrast to pessimistic_sig, cleared_sig might not have conDiv + -- Divergence! + cleared_sig = tryClearPreciseException fam_envs ty pessimistic_sig + sig_div = snd . splitStrictSig + no_change = sig_div cleared_sig == topDiv {- ************************************************************************ @@ -603,7 +640,7 @@ dmdFix top_lvl env let_dmd orig_pairs zapIdStrictness :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdStrictness pairs - = [(setIdStrictnessClearExn env id (emptySig topDiv), rhs) | (id, rhs) <- pairs ] + = [(setIdStrictnessClearExn env id topSig, rhs) | (id, rhs) <- pairs ] {- Note [Safe abortion in the fixed-point iteration] @@ -658,7 +695,7 @@ dmdAnalRhsLetDown rec_flag env let_dmd id rhs = mkRhsDmd env rhs_arity rhs (DmdType rhs_fv rhs_dmds rhs_div, rhs') = dmdAnal env rhs_dmd rhs - sig = mkStrictSigForArity rhs_arity (mkDmdType sig_fv rhs_dmds rhs_div) + sig = mkStrictSigForArity rhs_arity (DmdType sig_fv rhs_dmds rhs_div) id' = -- pprTraceWith "dmdAnalRhsLetDown" (\sig'-> ppr id <+> ppr sig <+> ppr sig') $ setIdStrictnessClearExn env id sig -- See Note [NOINLINE and strictness] @@ -944,9 +981,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -23,8 +23,7 @@ module GHC.Types.Demand ( DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType, BothDmdArg, mkBothDmdArg, toBothDmdArg, - emptyDmdType, botDmdType, mkDmdType, addDemand, - mayThrowPreciseDmdType, + emptyDmdType, botDmdType, addDemand, mayThrowPreciseDmdType, DmdEnv, emptyDmdEnv, peelFV, findIdDemand, @@ -33,7 +32,7 @@ module GHC.Types.Demand ( topDiv, botDiv, exnDiv, conDiv, appIsDeadEnd, isDeadEndSig, pprIfaceStrictSig, StrictSig(..), mkStrictSigForArity, mkClosedStrictSig, - emptySig, botSig, cprProdSig, + emptySig, topSig, botSig, cprProdSig, isTopSig, hasDemandEnvSig, splitStrictSig, strictSigDmdEnv, prependArgsStrictSig, etaConvertStrictSig, @@ -1275,6 +1274,9 @@ emptyDmdType div = DmdType emptyDmdEnv [] div botDmdType :: DmdType botDmdType = emptyDmdType botDiv +topDmdType :: DmdType +topDmdType = emptyDmdType topDiv + isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env @@ -1284,9 +1286,6 @@ mayThrowPreciseDmdType (DmdType _ _ Dunno) = True mayThrowPreciseDmdType (DmdType _ _ ExnOrDiv) = True mayThrowPreciseDmdType _ = False -mkDmdType :: DmdEnv -> [Demand] -> Divergence -> DmdType -mkDmdType fv ds res = DmdType fv ds res - dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1788,6 +1787,9 @@ emptySig div = StrictSig (emptyDmdType div) botSig :: StrictSig botSig = StrictSig botDmdType +topSig :: StrictSig +topSig = StrictSig topDmdType + cprProdSig :: Arity -> StrictSig cprProdSig _arity = emptySig conDiv -- constructor applications never throw precise exceptions ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -658,7 +658,7 @@ setIdCprInfo :: Id -> CprSig -> Id setIdCprInfo id sig = modifyIdInfo (\info -> setCprInfo info sig) id zapIdStrictness :: Id -> Id -zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` emptySig topDiv) id +zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id -- | This predicate says whether the 'Id' has a strict demand placed on it or -- has a type such that it can always be evaluated strictly (i.e an ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -324,7 +324,7 @@ vanillaIdInfo inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, - strictnessInfo = emptySig topDiv, + strictnessInfo = topSig, cprInfo = topCprSig, callArityInfo = unknownArity, levityInfo = NoLevityInfo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fcd81dbcb6a3368a4bba530930f583700c98c582 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fcd81dbcb6a3368a4bba530930f583700c98c582 You're receiving 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 8 11:29:50 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Wed, 08 Apr 2020 07:29:50 -0400 Subject: [Git][ghc/ghc][wip/T18023] Use conLikeUserTyVarBinders to quantify field selector types Message-ID: <5e8db5ae3d743_616776d1c743666725@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18023 at Glasgow Haskell Compiler / GHC Commits: 7cc4cd4c by Ryan Scott at 2020-04-08T07:29:31-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 12 changed files: - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/existential_quantification.rst - + docs/users_guide/exts/field_selectors_and_type_applications.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/rank_polymorphism.rst - docs/users_guide/exts/records.rst - + testsuite/tests/typecheck/should_compile/T18023.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/ConLike.hs ===================================== @@ -12,6 +12,7 @@ module GHC.Core.ConLike ( , conLikeArity , conLikeFieldLabels , conLikeInstOrigArgTys + , conLikeUserTyVarBinders , conLikeExTyCoVars , conLikeName , conLikeStupidTheta @@ -113,6 +114,18 @@ conLikeInstOrigArgTys (RealDataCon data_con) tys = conLikeInstOrigArgTys (PatSynCon pat_syn) tys = patSynInstArgTys pat_syn tys +-- | 'TyVarBinder's for the type variables of the 'ConLike'. For pattern +-- synonyms, this will always consist of the universally quantified variables +-- followed by the existentially quantified type variables. For data +-- constructors, the situation is slightly more complicated—see +-- @Note [DataCon user type variable binders]@ in "GHC.Core.DataCon". +conLikeUserTyVarBinders :: ConLike -> [TyVarBinder] +conLikeUserTyVarBinders (RealDataCon data_con) = + dataConUserTyVarBinders data_con +conLikeUserTyVarBinders (PatSynCon pat_syn) = + patSynUnivTyVarBinders pat_syn ++ patSynExTyVarBinders pat_syn + -- The order here is because of the order in `GHC.Tc.TyCl.PatSyn`. + -- | Existentially quantified type/coercion variables conLikeExTyCoVars :: ConLike -> [TyCoVar] conLikeExTyCoVars (RealDataCon dcon1) = dataConExTyCoVars dcon1 ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -384,7 +384,9 @@ data DataCon -- MkT :: forall a b. (a ~ [b]) => b -> T a -- MkT :: forall b. b -> T [b] -- Each equality is of the form (a ~ ty), where 'a' is one of - -- the universally quantified type variables + -- the universally quantified type variables. Moreover, the + -- only place in the DataCon where this 'a' will occur is in + -- dcUnivTyVars. See [The dcEqSpec domain invariant]. -- The next two fields give the type context of the data constructor -- (aside from the GADT constraints, @@ -595,6 +597,35 @@ dcUserTyVarBinders, as the name suggests, is the one that users will see most of the time. It's used when computing the type signature of a data constructor (see dataConUserType), and as a result, it's what matters from a TypeApplications perspective. + +Note [The dcEqSpec domain invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this example of a GADT constructor: + + data Y a where + MkY :: Bool -> Y Bool + +The user-written type of MkY is `Bool -> Y Bool`, but what is the underlying +Core type for MkY? There are two conceivable possibilities: + +1. MkY :: forall a. (a ~# Bool) => Bool -> Y a +2. MkY :: forall a. (a ~# Bool) => a -> Y a + +In practice, GHC picks (1) as the Core type for MkY. This is because we +maintain an invariant that the type variables in the domain of dcEqSpec will +only ever appear in the dcUnivTyVars. As a consequence, the type variables in +the domain of dcEqSpec will /never/ appear in the dcExTyCoVars, dcOtherTheta, +dcOrigArgTys, or dcOrigResTy; these can only ever mention variables from +dcUserTyVarBinders, which excludes things in the domain of dcEqSpec. +(See Note [DataCon user type variable binders].) This explains why GHC would +not pick (2) as the Core type, since the argument type `a` mentions a type +variable in the dcEqSpec. + +There are certain parts of the codebase where it is convenient to apply the +substitution arising from the dcEqSpec to the dcUnivTyVars in order to obtain +the user-written return type of a GADT constructor. A consequence of the +dcEqSpec domain invariant is that you /never/ need to apply the substitution +to any other part of the constructor type, as they don't require it. -} -- | Data Constructor Representation ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -645,11 +645,7 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields mk_alt upd_fld_env con = do { let (univ_tvs, ex_tvs, eq_spec, prov_theta, _req_theta, arg_tys, _) = conLikeFullSig con - user_tvs = - case con of - RealDataCon data_con -> dataConUserTyVars data_con - PatSynCon _ -> univ_tvs ++ ex_tvs - -- The order here is because of the order in `GHC.Tc.TyCl.PatSyn`. + user_tvs = binderVars $ conLikeUserTyVarBinders con in_subst = zipTvSubst univ_tvs in_inst_tys out_subst = zipTvSubst univ_tvs out_inst_tys ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -872,19 +872,17 @@ mkOneRecordSelector all_cons idDetails fl -- Selector type; Note [Polymorphic selectors] field_ty = conLikeFieldType con1 lbl - data_tvs = tyCoVarsOfTypesWellScoped inst_tys - data_tv_set= mkVarSet data_tvs + data_tvbs = filter (\tvb -> binderVar tvb `elemVarSet` data_tv_set) $ + conLikeUserTyVarBinders con1 + data_tv_set= tyCoVarsOfTypes inst_tys is_naughty = not (tyCoVarsOfType field_ty `subVarSet` data_tv_set) - (field_tvs, field_theta, field_tau) = tcSplitSigmaTy field_ty sel_ty | is_naughty = unitTy -- See Note [Naughty record selectors] - | otherwise = mkSpecForAllTys data_tvs $ + | otherwise = mkForAllTys data_tvbs $ mkPhiTy (conLikeStupidTheta con1) $ -- Urgh! - mkVisFunTy data_ty $ - mkSpecForAllTys field_tvs $ - mkPhiTy field_theta $ -- req_theta is empty for normal DataCon mkPhiTy req_theta $ - field_tau + mkVisFunTy data_ty $ + field_ty -- Make the binding: sel (C2 { fld = x }) = x -- sel (C7 { fld = x }) = x @@ -936,6 +934,16 @@ mkOneRecordSelector all_cons idDetails fl (univ_tvs, _, eq_spec, _, req_theta, _, data_ty) = conLikeFullSig con1 eq_subst = mkTvSubstPrs (map eqSpecPair eq_spec) + -- inst_tys corresponds to one of the following: + -- + -- * The arguments to the user-written return type (for GADT constructors). + -- In this scenario, eq_subst provides a mapping from the universally + -- quantified type variables to the argument types. Note that eq_subst + -- does not need to be applied to any other part of the DataCon + -- (see Note [The dcEqSpec domain invariant] in GHC.Core.DataCon). + -- * The universally quantified type variables + -- (for Haskell98-style constructors and pattern synonyms). In these + -- scenarios, eq_subst is an empty substitution. inst_tys = substTyVars eq_subst univ_tvs unit_rhs = mkLHsTupleExpr [] @@ -945,13 +953,44 @@ mkOneRecordSelector all_cons idDetails fl Note [Polymorphic selectors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We take care to build the type of a polymorphic selector in the right -order, so that visible type application works. - - data Ord a => T a = MkT { field :: forall b. (Num a, Show b) => (a, b) } - -We want - - field :: forall a. Ord a => T a -> forall b. (Num a, Show b) => (a, b) +order, so that visible type application works according to the specification in +the GHC User's Guide (see the "Field selectors and TypeApplications" section). +We won't bother rehashing the entire specification in this Note, but the tricky +part is dealing with GADT constructor fields. Here is an appropriately tricky +example to illustrate the challenges: + + {-# LANGUAGE PolyKinds #-} + data T a b where + MkT :: forall b a x. + { field1 :: forall c. (Num a, Show c) => (Either a c, Proxy b) + , field2 :: x + } + -> T a b + +Our goal is to obtain the following type for `field1`: + + field1 :: forall {k} (b :: k) a. + T a b -> forall c. (Num a, Show c) => (Either a c, Proxy b) + +(`field2` is naughty, per Note [Naughty record selectors], so we cannot turn +it into a top-level field selector.) + +Some potential gotchas, inspired by #18023: + +1. Since the user wrote `forall b a x.` in the type of `MkT`, we want the `b` + to appear before the `a` when quantified in the type of `field1`. +2. On the other hand, we *don't* want to quantify `x` in the type of `field1`. + This is because `x` does not appear in the GADT return type, so it is not + needed in the selector type. +3. Because of PolyKinds, the kind of `b` is generalized to `k`. Moreover, since + this `k` is not written in the source code, it is inferred (i.e., not + available for explicit type applications) and thus written as {k} in the type + of `field1`. + +In order to address these gotchas, we start by looking at the +conLikeUserTyVarBinders, which gives the order and specificity of each binder. +This effectively solves (1) and (3). To solve (2), we filter the binders to +leave only those that are needed for the selector type. Note [Naughty record selectors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -18,6 +18,34 @@ Full details Language ~~~~~~~~ +* Record field selectors are now given type signatures that preserve the + user-written order of quantified type variables. Moreover, field selector + type signatures no longer make inferred type variables avaiable for explicit + type application. See :ref:`field-selectors-and-type-applications` for more + details. + + In certain situations, this will constitute a breaking change as this can + affect :extension:`TypeApplications`. For instance, given the following + definitions: :: + + {-# LANGUAGE PolyKinds #-} + + newtype P a = MkP { unP :: Proxy a } + + newtype N :: Type -> Type -> Type where + MkN :: forall b a. { unN :: Either a b } -> N a b + + Previous versions of GHC would give the following types to ``unP`` and + ``unN``: :: + + unP :: forall k (a :: k). P a -> Proxy a + unN :: forall a b. N a b -> Either a b + + GHC will now give them the following types instead: :: + + unP :: forall {k} (a :: k). P a -> Proxy a + unN :: forall b a. N a b -> Either a b + * In obscure scenarios, GHC now rejects programs it previously accepted, but with unhelpful types. For example, if (with ``-XPartialTypeSignatures``) you were to write ``x :: forall (f :: forall a (b :: a -> Type). b _). f _``, GHC previously @@ -40,7 +68,7 @@ Language There is a chance we will tweak the lookup scheme in the future, to make this workaround unnecessary. - + Compiler ~~~~~~~~ ===================================== docs/users_guide/exts/existential_quantification.rst ===================================== @@ -116,7 +116,11 @@ example: :: } Here ``tag`` is a public field, with a well-typed selector function -``tag :: Counter a -> a``. The ``self`` type is hidden from the outside; +``tag :: Counter a -> a``. See :ref:`field-selectors-and-type-applications` +for a full description of how the types of top-level field selectors are +determined. + +The ``self`` type is hidden from the outside; any attempt to apply ``_this``, ``_inc`` or ``_display`` as functions will raise a compile-time error. In other words, *GHC defines a record selector function only for fields whose type does not mention the ===================================== docs/users_guide/exts/field_selectors_and_type_applications.rst ===================================== @@ -0,0 +1,122 @@ +.. _field-selectors-and-type-applications: + +Field selectors and ``TypeApplications`` +---------------------------------------- + +Field selectors can be used in conjunction with :extension:`TypeApplications`, +as described in :ref:`visible-type-application`. The type of a field selector +is constructed by using the surrounding definition as context. This section +provides a specification for how this construction works. We will explain it +by considering three different forms of field selector, each of which is a +minor variation of the same general theme. + +Field selectors for Haskell98-style data constructors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider the following example: :: + + data T a b = MkT { unT :: forall e. Either e a } + +This data type uses a Haskell98-style declaration. The only part of this data +type that is not Haskell98 code is ``unT``, whose type uses higher-rank +polymorphism (:ref:`arbitrary-rank-polymorphism`). To construct the type of +the ``unT`` field selector, we will assemble the following: + +1. The type variables quantified by the data type head + (``forall a b. <...>``). +2. The return type of the data constructor + (``<...> T a b -> <...>``). By virtue of this being a Haskell98-style + declaration, the order of type variables in the return type will always + coincide with the order in which they are quantified. +3. The type of the field + (``<...> forall e. Either e a``). + +The final type of ``unT`` is therefore +``forall a b. T a b -> forall e. Either e a``. As a result, one way to use +``unT`` with :extension:`TypeApplications` is +``unT @Int @Bool (MkT (Right 1)) @Char``. + +Field selectors for GADT constructors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Field selectors for GADT constructors (:ref:`gadt-style`) are slightly more +involved. Consider the following example: :: + + data G a b where + MkG :: forall x n a. (Eq a, Show n) + => { unG1 :: forall e. Either e (a, x), unG2 :: n } -> G a (Maybe x) + +The ``MkG`` GADT constructor has two records, ``unG1`` and ``unG2``. +However, only ``unG1`` can be used as a top-level field selector. ``unG2`` +cannot because it is a "hidden" selector (see :ref:`existential-records`); its +type mentions a free variable ``n`` that does not appear in the result type +``G a (Maybe x)``. On the other hand, the only free type variables in the type +of ``unG1`` are ``a`` and ``x``, so ``unG1`` is fine to use as a top-level +function. + +To construct the type of the ``unG1`` field selector, we will assemble +the following: + +1. The subset of type variables quantified by the GADT constructor that are + mentioned in the return type. Note that the order of these variables follows + the same principles as in :ref:`ScopedSort`. + If the constructor explicitly quantifies its type variables at the beginning + of the type, then the field selector type will quantify them in the same + order (modulo any variables that are dropped due to not being mentioned in + the return type). + If the constructor implicitly quantifies its type variables, then the field + selector type will quantify them in the left-to-right order that they appear + in the field itself. + + In this example, ``MkG`` explicitly quantifies ``forall x n a.``, and of + those type variables, ``a`` and ``x`` are mentioned in the return type. + Therefore, the type of ``unG1`` starts as ``forall x a. <...>``. + If ``MkG`` had not used an explicit ``forall``, then they would have instead + been ordered as ``forall a x. <...>``, since ``a`` appears to the left of + ``x`` in the field type. +2. The GADT return type + (``<...> G a (Maybe x) -> ...``). +3. The type of the field + (``<...> -> forall e. Either e (a, x)``). + +The final type of ``unG1`` is therefore +``forall x a. G a (Maybe x) -> forall e. Either e (a, x)``. As a result, one +way to use ``unG1`` with :extension:`TypeApplications` is +``unG1 @Int @Bool (MkG (Right (True, 42)) ()) @Char``. + +Field selectors for pattern synonyms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Certain record pattern synonyms (:ref:`record-patsyn`) can give rise to +top-level field selectors. Consider the following example: :: + + pattern P :: forall a. Read a + => forall n. (Eq a, Show n) + => (forall e. Either e (a, Bool)) -> n -> G a (Maybe Bool) + pattern P {unP1, unP2} = MkG unP1 unP2 + +We can only make field selectors for pattern synonym records that do not +mention any existential type variables whatsoever in their types, per +:ref:`record-patsyn`. (This is a stronger requirement than for GADT records, +whose types can mention existential type variables provided that they are also +mentioned in the return type.) We can see that ``unP2`` cannot be used as a +top-level field selector since its type has a free type variable ``n``, which +is existential. ``unP1`` is fine, on the other hand, as its type only has one +free variable, the universal type variable ``a``. + +To construct the type of the ``unP1`` field selector, we will assemble +the following: + +1. The universal type variables + (``forall a. <...>``). +2. The required constraints + (``<...> Read a => <...>``). +3. The pattern synonym return type + (``<...> G a (Maybe Bool) -> <...>``). +4. The type of the field + (``<...> -> forall e. Either e (a, Bool)``). + +The final type of ``unP1`` is therefore +``forall a. Read a => G a (Maybe Bool) -> forall e. Either e (a, Bool)``. As a +result, one way to use ``unP1`` with :extension:`TypeApplications` is +``unP1 @Double (MkG (Right (4.5, True)) ()) @Char``. ===================================== docs/users_guide/exts/gadt.rst ===================================== @@ -118,6 +118,9 @@ also sets :extension:`GADTSyntax` and :extension:`MonoLocalBinds`. num :: Term Int -> Term Int arg :: Term Bool -> Term Int + See :ref:`field-selectors-and-type-applications` for a full description of + how the types of top-level field selectors are determined. + - When pattern-matching against data constructors drawn from a GADT, for example in a ``case`` expression, the following rules apply: ===================================== docs/users_guide/exts/rank_polymorphism.rst ===================================== @@ -1,3 +1,5 @@ +.. _arbitrary-rank-polymorphism: + Arbitrary-rank polymorphism =========================== ===================================== docs/users_guide/exts/records.rst ===================================== @@ -7,6 +7,7 @@ Records :maxdepth: 1 traditional_record_syntax + field_selectors_and_type_applications disambiguate_record_fields duplicate_record_fields record_puns ===================================== testsuite/tests/typecheck/should_compile/T18023.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +module T18023 where + +import Data.Kind +import Data.Proxy + +newtype N :: Type -> Type -> Type where + MkN :: forall b a. { unN :: Either a b } -> N a b + +toN :: Either Int Bool -> N Int Bool +toN = MkN @Bool @Int + +fromN :: N Int Bool -> Either Int Bool +fromN = unN @Bool @Int + +newtype P a = MkP { unP :: Proxy a } + +toPTrue :: Proxy True -> P True +toPTrue = MkP @True + +fromPTrue :: P True -> Proxy True +fromPTrue = unP @True + +newtype P2 a b = MkP2 { unP2 :: (Proxy a, Proxy b) } + +toP2True :: (Proxy True, Proxy True) -> P2 True True +toP2True = MkP2 @True @True + +fromP2True :: P2 True True -> (Proxy True, Proxy True) +fromP2True = unP2 @True @True ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -702,3 +702,4 @@ test('T17792', normal, compile, ['']) test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) +test('T18023', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cc4cd4cbc8d3cc8b03fbced9b57cf6b266fecf7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cc4cd4cbc8d3cc8b03fbced9b57cf6b266fecf7 You're receiving 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 8 13:13:13 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 08 Apr 2020 09:13:13 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: simplifier: Kill off ufKeenessFactor Message-ID: <5e8dcde91bf6a_61673f81cc90b39c36846e0@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 3ff8d360 by Ryan Scott at 2020-04-08T09:12:58-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Flags.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/087e84e1c97dfd41ef4f3baaf810caef0b6a9c05...3ff8d3604b3dc946f968347aa524a4436efee18d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/087e84e1c97dfd41ef4f3baaf810caef0b6a9c05...3ff8d3604b3dc946f968347aa524a4436efee18d You're receiving 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 8 15:38:03 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 08 Apr 2020 11:38:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/smaller-coreView Message-ID: <5e8defdbd050c_61673f8199536d94372528@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/smaller-coreView at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/smaller-coreView You're receiving 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 8 17:31:19 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 08 Apr 2020 13:31:19 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Rework treatment of `elem`. Add UTF8 GHC.CString functions. Message-ID: <5e8e0a673ee67_6167136dfb9c37808ac@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 15ca17aa by Andreas Klebinger at 2020-04-08T18:11:44+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. This now also works for unboxed string literals via a builtin rule. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors and was required to support this transformation for utf8 encoded unboxed strings. - - - - - 13 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Op/ConstantFold.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/prelude/PrelNames.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.Make ( sortQuantVars, castBottomExpr, -- * Constructing boxed literals + trueExpr, falseExpr, mkWordExpr, mkWordExprWord, mkIntExpr, mkIntExprInt, mkIntegerExpr, mkNaturalExpr, @@ -248,6 +249,10 @@ castBottomExpr e res_ty ************************************************************************ -} +trueExpr, falseExpr :: CoreExpr +trueExpr = Var trueDataConId +falseExpr = Var falseDataConId + -- | Create a 'CoreExpr' which will evaluate to the given @Int@ mkIntExpr :: Platform -> Integer -> CoreExpr -- Result = I# i :: Int mkIntExpr platform i = mkCoreConApps intDataCon [mkIntLit platform i] ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -34,7 +34,8 @@ import GHC.Core import GHC.Core.Make import GHC.Types.Id import GHC.Types.Literal -import GHC.Core.SimpleOpt ( exprIsLiteral_maybe ) +import GHC.Core.SimpleOpt ( exprIsLiteral_maybe, exprIsLambda_maybe + , exprIsStrippableLiteral_maybe ) import PrimOp ( PrimOp(..), tagToEnumKey ) import TysWiredIn import TysPrim @@ -57,6 +58,7 @@ import GHC.Types.Basic import GHC.Platform import Util import GHC.Core.Coercion (mkUnbranchedAxInstCo,mkSymCo,Role(..)) +import Encoding (utf8DecodeByteString) import Control.Applicative ( Alternative(..) ) @@ -67,6 +69,7 @@ import Data.Int import Data.Ratio import Data.Word + {- Note [Constant folding] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1254,11 +1257,18 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, + BuiltinRule { ru_name = fsLit "AppendLitStringUtf8", + ru_fn = unpackCStringFoldrUtf8Name, + ru_nargs = 4, ru_try = match_append_lit_utf8 }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, ru_nargs = 2, ru_try = \_ _ _ -> match_inline }, + + -- See Note [Compiling `elem` applied to known strings] + BuiltinRule { ru_name = fsLit "ElemLitString", ru_fn = elemName, + ru_nargs = 4, ru_try = match_elem }, BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId, ru_nargs = 4, ru_try = \_ _ _ -> match_magicDict }, @@ -1430,11 +1440,20 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo" c (unpackFoldrCString*# "baz" c n) +-- = unpackFoldrCString*# "foobaz" c n + +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +-- CStringUTF8 version +match_append_lit_utf8 :: RuleFun +match_append_lit_utf8 = match_append_lit unpackCStringFoldrUtf8IdKey + +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,7 +1466,7 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey + , unpk `hasKey` foldVariant , cheapEqExpr' tickishFloatable c1 c2 , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 , c2Ticks <- stripTicksTopT tickishFloatable c2 @@ -1460,23 +1479,149 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)) = s1==s2 +-- Also matches unpackCStringUtf8# match_eq_string :: RuleFun match_eq_string _ id_unf _ [Var unpk1 `App` lit1, Var unpk2 `App` lit2] - | unpk1 `hasKey` unpackCStringIdKey - , unpk2 `hasKey` unpackCStringIdKey + | unpk_key1 <- getUnique unpk1 + , unpk_key2 <- getUnique unpk2 + , unpk_key1 == unpk_key2 + , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 = Just (if s1 == s2 then trueValBool else falseValBool) match_eq_string _ _ _ _ = Nothing +{- Note [Compiling `elem` applied to known strings] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We start of with this userwritten code in haskell + + elem x "" + +which we would like to transform into: + + case x of + 'k' -> True + 'k' -> True + '_' -> True + +For lists this would happen automatically via rules +associated with elem. However these do not fire for +string literals as we do not translate string literals +into actual lists for performance reasons. (At least +past a certain string size) + +For string literals what happens in abensence of any +built in rules what would happen is: + +1) Start with: + elem x "" +2) Desugar: + elem x (unpackCString# ""#) +3) Apply "unpack" RULE in GHC.Base: [Phase 2 and earlier] + elem x (build (unpackFoldrCString# ""#)) +3) Apply "build/elem" rule [Phase 2 and later] + + inline foldCString# [Phase 0]: + + joinrec { + unpack_a1ui (nh_ayh :: Int#) + = case indexCharOffAddr# addr_ayd nh_ayh of ch_a1uv { + __DEFAULT -> + case x_ayj of { C# x1_a1Jr -> + case eqChar# x1_a1Jr ch_a1uv of { + __DEFAULT -> jump unpack_a1ui (+# nh_ayh 1#); + 1# -> GHC.Types.True + } + }; + '\NUL'# -> GHC.Types.False + }; } in + jump unpack_a1ui 0# + } + +Which is not *bad* we do not allocate, but we perform linear search +on the string. + +So instead we use match_elem to look for applications of elem to known +strings during all phases and transform them into case expressions +explicitly. Depending on the content of the string we then end up +with either a decision trees or lookup tables. + +Userwritten patterns of `elem x ""` will all +be caught during the initial phase since we match on both the +desugared form and the form after applying the "unpack" rule. +So it does not matter which rule ends up firing first. + +Should we get this pattern in a later pass it's a toin coss +if we get a case statement or linear search. But linear search +isn't bad enough to loose sleep over this scenario. + +The only exception is that we disable this rule for overly large +strings (>= 500 bytes). This avoid code size blow up if we check +for many sparse values. + +-} + +--------------------------------------------------- +-- The rule is this: +-- elem x +-- = case x of C# x' +-- case x' of - +-- 'a'# -> True +-- 'b'# -> True +-- 'c'# -> True +-- _ -> False +-- +-- Where knownString is one of: +-- * (build ((unpackFoldrCString# "abc"#) +-- * (unpackCString*# "abc"#) +-- Limits matches to strings <=500 bytes. +-- Also matches utf8 versions. + +-- See Note Note [Compiling `elem` applied to known strings] +match_elem :: RuleFun +match_elem _ id_unf _ [Type ty, _dict, x, xs] + -- elem on string + | ty `eqType` charTy + , ( xsTicks, xsApp) <- stripTicksTop tickishFloatable xs + -- Can we get the string + , Just (lam_ticks, litExpr) <- getLitStringExpr xsApp + , Just (LitString s1, litTicks) <- exprIsStrippableLiteral_maybe id_unf tickishFloatable litExpr + -- For really large strings we fall back to the default implementation. + , BS.length s1 <= 500 + = let elem_string = nubSort $ utf8DecodeByteString s1 :: String + x_id = mkWildValBinder charTy :: Id + x_prim_id = mkWildValBinder charPrimTy :: Id + switch = Case (Var x_prim_id) x_prim_id boolTy + ((DEFAULT, [], falseExpr):foldr mkCharAlt [] elem_string) + mkCharAlt :: Char -> [CoreAlt] -> [CoreAlt] + mkCharAlt c alts = (LitAlt (mkLitChar c), [], trueExpr):alts + in Just $ mkTicks (xsTicks ++ lam_ticks ++ litTicks) + $ Case x x_id boolTy [(DataAlt charDataCon, [x_prim_id], switch)] + where + getLitStringExpr :: CoreExpr -> Maybe ([Tickish Id], CoreExpr) + getLitStringExpr app + -- (build ((unpackFoldrCString*# "abc"#))) + | (Var build `App` _char_ty `App` unf_str_app) <- app + , build `hasKey` buildIdKey + , Just (_arg, (Var unfold_str `App` _ty2 `App` lit1), lam_ticks) + <- exprIsLambda_maybe id_unf unf_str_app + , getUnique unfold_str `elem` [unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey] + = Just (lam_ticks, lit1) + -- (unpackCString*# "abc"#) + | (Var unpackVar `App` lit1) <- app + , getUnique unpackVar `elem` [unpackCStringIdKey, unpackCStringUtf8IdKey] + = Just ([], lit1) + | otherwise = Nothing + +match_elem _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Core.SimpleOpt ( -- ** Predicates on expressions exprIsConApp_maybe, exprIsLiteral_maybe, exprIsLambda_maybe, + exprIsStrippableLiteral_maybe, -- ** Coercions and casts pushCoArg, pushCoValArg, pushCoTyArg, collectBindersPushingCo @@ -1156,6 +1157,20 @@ exprIsLiteral_maybe env@(_, id_unf) e -> exprIsLiteral_maybe env rhs _ -> Nothing +exprIsStrippableLiteral_maybe :: InScopeEnv -> (Tickish Id -> Bool) -> CoreExpr -> Maybe (Literal, [Tickish Id]) +-- Similar to exprIsLiteral_maybe but fails instead of dropping ticks +-- This means Tick t (Lit l) *can return Nothing*. So use with care +exprIsStrippableLiteral_maybe (_, id_unf) strip expr + = go [] expr + where + go ts e = case e of + Lit l -> Just (l,ts) + Tick t e' + | strip t -> go (t:ts) e' + Var v | Just rhs <- expandUnfolding_maybe (id_unf v) + -> go ts rhs + _ -> Nothing + {- Note [exprIsLambda_maybe] ~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -340,8 +340,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, -- Overloaded lists isListClassName, @@ -352,6 +352,7 @@ basicKnownKeyNames -- List operations concatName, filterName, mapName, zipName, foldrName, buildName, augmentName, appendName, + elemName, -- FFI primitive types that are not wired-in. stablePtrTyConName, ptrTyConName, funPtrTyConName, @@ -677,9 +678,10 @@ ordClass_RDR = nameRdrName ordClassName enumClass_RDR = nameRdrName enumClassName monadClass_RDR = nameRdrName monadClassName -map_RDR, append_RDR :: RdrName +map_RDR, append_RDR, elem_RDR :: RdrName map_RDR = nameRdrName mapName append_RDR = nameRdrName appendName +elem_RDR = nameRdrName elemName foldr_RDR, build_RDR, returnM_RDR, bindM_RDR, failM_RDR :: RdrName @@ -712,11 +714,12 @@ ioDataCon_RDR :: RdrName ioDataCon_RDR = nameRdrName ioDataConName eqString_RDR, unpackCString_RDR, unpackCStringFoldr_RDR, - unpackCStringUtf8_RDR :: RdrName + unpackCStringFoldrUtf8_RDR, unpackCStringUtf8_RDR :: RdrName eqString_RDR = nameRdrName eqStringName unpackCString_RDR = nameRdrName unpackCStringName unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name +unpackCStringFoldrUtf8_RDR = nameRdrName unpackCStringFoldrUtf8Name newStablePtr_RDR :: RdrName newStablePtr_RDR = nameRdrName newStablePtrName @@ -1006,11 +1009,12 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name,eqStringName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -1083,7 +1087,7 @@ groupWithName = varQual gHC_EXTS (fsLit "groupWith") groupWithIdKey -- Random PrelBase functions fromStringName, otherwiseIdName, foldrName, buildName, augmentName, - mapName, appendName, assertName, + mapName, appendName, elemName, assertName, breakpointName, breakpointCondName, opaqueTyConName, dollarName :: Name dollarName = varQual gHC_BASE (fsLit "$") dollarIdKey @@ -1097,6 +1101,7 @@ assertName = varQual gHC_BASE (fsLit "assert") assertIdKey breakpointName = varQual gHC_BASE (fsLit "breakpoint") breakpointIdKey breakpointCondName= varQual gHC_BASE (fsLit "breakpointCond") breakpointCondIdKey opaqueTyConName = tcQual gHC_BASE (fsLit "Opaque") opaqueTyConKey +elemName = varQual gHC_LIST (fsLit "elem") elemIdKey fromStringName = varQual dATA_STRING (fsLit "fromString") fromStringClassOpKey -- PrelTup @@ -2081,13 +2086,15 @@ unsafeReflDataConKey = mkPreludeDataConUnique 114 -} wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, + elemIdKey, buildIdKey, errorIdKey, foldrIdKey, recSelErrorIdKey, seqIdKey, eqStringIdKey, noMethodBindingErrorIdKey, nonExhaustiveGuardsErrorIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey :: Unique @@ -2095,27 +2102,29 @@ wildCardKey = mkPreludeMiscIdUnique 0 -- See Note [WildCard absentErrorIdKey = mkPreludeMiscIdUnique 1 augmentIdKey = mkPreludeMiscIdUnique 2 appendIdKey = mkPreludeMiscIdUnique 3 -buildIdKey = mkPreludeMiscIdUnique 4 -errorIdKey = mkPreludeMiscIdUnique 5 -foldrIdKey = mkPreludeMiscIdUnique 6 -recSelErrorIdKey = mkPreludeMiscIdUnique 7 -seqIdKey = mkPreludeMiscIdUnique 8 -absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 9 -eqStringIdKey = mkPreludeMiscIdUnique 10 -noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 11 -nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 12 -runtimeErrorIdKey = mkPreludeMiscIdUnique 13 -patErrorIdKey = mkPreludeMiscIdUnique 14 -realWorldPrimIdKey = mkPreludeMiscIdUnique 15 -recConErrorIdKey = mkPreludeMiscIdUnique 16 -unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 17 -unpackCStringAppendIdKey = mkPreludeMiscIdUnique 18 -unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 19 -unpackCStringIdKey = mkPreludeMiscIdUnique 20 -voidPrimIdKey = mkPreludeMiscIdUnique 21 -typeErrorIdKey = mkPreludeMiscIdUnique 22 -divIntIdKey = mkPreludeMiscIdUnique 23 -modIntIdKey = mkPreludeMiscIdUnique 24 +elemIdKey = mkPreludeMiscIdUnique 4 +buildIdKey = mkPreludeMiscIdUnique 5 +errorIdKey = mkPreludeMiscIdUnique 6 +foldrIdKey = mkPreludeMiscIdUnique 7 +recSelErrorIdKey = mkPreludeMiscIdUnique 8 +seqIdKey = mkPreludeMiscIdUnique 9 +absentSumFieldErrorIdKey = mkPreludeMiscIdUnique 10 +eqStringIdKey = mkPreludeMiscIdUnique 11 +noMethodBindingErrorIdKey = mkPreludeMiscIdUnique 12 +nonExhaustiveGuardsErrorIdKey = mkPreludeMiscIdUnique 13 +runtimeErrorIdKey = mkPreludeMiscIdUnique 14 +patErrorIdKey = mkPreludeMiscIdUnique 15 +realWorldPrimIdKey = mkPreludeMiscIdUnique 16 +recConErrorIdKey = mkPreludeMiscIdUnique 17 +unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 18 +unpackCStringAppendIdKey = mkPreludeMiscIdUnique 19 +unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 20 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 21 +unpackCStringIdKey = mkPreludeMiscIdUnique 22 +voidPrimIdKey = mkPreludeMiscIdUnique 23 +typeErrorIdKey = mkPreludeMiscIdUnique 24 +divIntIdKey = mkPreludeMiscIdUnique 25 +modIntIdKey = mkPreludeMiscIdUnique 26 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1618,7 +1618,11 @@ iShiftRL# :: Int# -> Int# -> Int# a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# | otherwise = a `uncheckedIShiftRL#` b +------------------------------------------------------------------------ -- Rules for C strings (the functions themselves are now in GHC.CString) +------------------------------------------------------------------------ + +-- Ascii variants {-# RULES "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a @@ -1628,3 +1632,14 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n #-} + +-- Utf8 variants +{-# RULES +"unpackUtf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-listUtf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-appendUtf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + +-- There's a built-in rule (in PrelRules.hs) for +-- unpackFoldrUtf8 "föö" c (unpackFoldrUtf8 "bäz" c n) = unpackFoldrUtf8 "fööbäz" c n + + #-} ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,9 +1149,10 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" [2] forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} + #endif -- | 'notElem' is the negation of 'elem'. @@ -1174,7 +1175,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" [2] forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -9,6 +9,13 @@ * Add `hGetContents'`, `getContents'`, and `readFile'` in `System.IO`: Strict IO variants of `hGetContents`, `getContents`, and `readFile`. + * Add rules `unpackUtf8`, `unpack-listUtf8` and `unpack-appendUtf8` to `GHC.Base`. + They correspond to their ascii versions and hopefully make it easier + to handle utf8 encoded strings efficiently. + + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement as expected. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,17 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques + # We only grep for specific patterns to minimize failures when eg core syntax changes + # We expect two unfolds using eqChar + echo $$(cat T17752.dump-simpl | grep unpackFoldrCString) + echo $$(cat T17752.dump-simpl | grep eqChar) + # And two pattern matches + echo $$(cat T17752.dump-simpl | grep "case x1" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,84 @@ +module T17752 where + +-- Should compile to unfoldCStr if the rules fire +isElemLit x = x `elem` "theQuickShinyGHCJumpsOverTheRuleRecursion" +isNotElemLit x = x `notElem` "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion" + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +isOneOfThese x = x `elem` [1,2,3,4,5::Int] + +{- + +Should the grep tests fail make sure the core still behaves +like the one below (or better!) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isElemLit1 = "theQuickShinyGHCJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 20, types: 9, coercions: 0, joins: 0/0} +isElemLit + = \ x -> + unpackFoldrCString# + isElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +isNotElemLit1 + = "_theQuickShinyGHCCompileJumpsOverTheRuleRecursion"# + +-- RHS size: {terms: 25, types: 10, coercions: 0, joins: 0/0} +isNotElemLit + = \ x -> + case unpackFoldrCString# + isNotElemLit1 + (\ y r -> + case x of { C# x1 -> + case y of { C# y1 -> + case eqChar# x1 y1 of { + __DEFAULT -> r; + 1# -> True + } + } + }) + False + of { + False -> True; + True -> False + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'a'# -> True; + 'b'# -> True; + 'c'# -> True + } + } + +-- RHS size: {terms: 14, types: 4, coercions: 0, joins: 0/0} +isNotElemList + = \ x -> + case x of { C# x1 -> + case x1 of { + __DEFAULT -> False; + 'x'# -> True; + 'y'# -> True; + 'z'# -> True + } + } +-} ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,25 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) +GHC.CString.unpackFoldrCString# + case GHC.CString.unpackFoldrCString# +case GHC.Prim.eqChar# x1 y1 of { + case GHC.Prim.eqChar# x1 y1 of { +case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'a'# -> GHC.Types.True; + 'b'# -> GHC.Types.True; + 'c'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True + -- case x1 of { + __DEFAULT -> GHC.Types.False; + 'x'# -> GHC.Types.True; + 'y'# -> GHC.Types.True; + 'z'# -> GHC.Types.True ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) \ No newline at end of file ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,8 +17,14 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types @@ -71,8 +77,24 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Inlining of unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n + +We use NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. + +This can cause a code size increase but it was minimal +when looking at nofib. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +111,12 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. +If we use the offset start off with the increment and an addition +to get the real address. Which might not be optimized aways. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +139,17 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- See [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +157,43 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +212,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explicit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,13 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15ca17aa375a9460c95d31151c8ca0388b8f037b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15ca17aa375a9460c95d31151c8ca0388b8f037b You're receiving 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 8 17:43:33 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Wed, 08 Apr 2020 13:43:33 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Pure refactor of code around ConPat Message-ID: <5e8e0d45a8609_61673f8198ee100c37851ee@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 63e007f1 by Cale Gibbard at 2020-04-08T13:40:48-04:00 Pure refactor of code around ConPat Now that things are working, clean some things up: - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently - - - - - 26 changed files: - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Types.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - compiler/typecheck/TcArrows.hs - compiler/typecheck/TcBinds.hs - compiler/typecheck/TcGenDeriv.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcPat.hs - compiler/typecheck/TcPatSyn.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/typecheck/TcTyDecls.hs - compiler/typecheck/TcValidity.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -662,7 +662,6 @@ type family XListPat x type family XTuplePat x type family XSumPat x type family XConPat x -type family XConPatCon x type family XViewPat x type family XSplicePat x type family XLitPat x ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -23,10 +23,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, ConPatTc (..), CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -72,12 +73,10 @@ import GHC.Core.Type import SrcLoc import Bag -- collect ev vars from pats import Maybes +import Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat GhcTc -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -175,9 +174,9 @@ data Pat p ------------ Constructor patterns --------------- | ConPat { - pat_con :: Located (XConPatCon p), - pat_args :: HsConPatDetails p, - pat_con_ext :: XConPat p + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } -- ^ Constructor Pattern @@ -282,10 +281,6 @@ type instance XConPat GhcPs = NoExtField type instance XConPat GhcRn = NoExtField type instance XConPat GhcTc = ConPatTc -type instance XConPatCon GhcPs = IdP GhcPs -type instance XConPatCon GhcRn = IdP GhcRn -type instance XConPatCon GhcTc = ConLike - type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -313,6 +308,11 @@ type instance XXPat GhcPs = NoExtCon type instance XXPat GhcRn = NoExtCon type instance XXPat GhcTc = CoPat +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -329,26 +329,26 @@ data ConPatTc = ConPatTc { -- | The universal arg types 1-1 with the universal -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get + -- Use (conLikeResTy pat_con cpt_arg_tys) to get -- the type of the pattern - pat_arg_tys :: [Type] + cpt_arg_tys :: [Type] , -- | Existentially bound type variables -- in correctly-scoped order e.g. [k:* x:k] - pat_tvs :: [TyVar] + cpt_tvs :: [TyVar] , -- | Ditto *coercion variables* and *dictionaries* -- One reason for putting coercion variable here I think -- is to ensure their kinds are zonked - pat_dicts :: [EvVar] + cpt_dicts :: [EvVar] , -- | Bindings involving those dictionaries - pat_binds :: TcEvBinds + cpt_binds :: TcEvBinds , -- ^ Extra wrapper to pass to the matcher -- Only relevant for pattern-synonyms; -- ignored for data cons - pat_wrap :: HsWrapper + cpt_wrap :: HsWrapper } -- | Coercion Pattern (translation only) @@ -360,7 +360,7 @@ data CoPat { -- | Coercion Pattern -- If co :: t1 ~ t2, p :: t2, -- then (CoPat co p) :: t1 - co_pat_wrap :: HsWrapper + co_cpt_wrap :: HsWrapper , -- | Why not LPat? Ans: existing locn will do co_pat_inner :: Pat GhcTc @@ -523,16 +523,14 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat - :: forall p - . OutputableBndrId p - => PprPrec - -> Pat (GhcPass p) - -> SDoc +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> if need_parens print_tc_elab pat then parens (pprPat pat) - else pprPat pat + else pprPat pat where need_parens print_tc_elab pat | GhcTc <- ghcPass @p @@ -547,7 +545,7 @@ pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_ela -- But otherwise the CoPat is discarded, so it -- is the pattern inside that matters. Sigh. -pprPat :: forall p. (IsPass p, OutputableBndrId p) => Pat (GhcPass p) -> SDoc +pprPat :: forall p. (OutputableBndrId p) => Pat (GhcPass p) -> SDoc pprPat (VarPat _ lvar) = pprPatBndr (unLoc lvar) pprPat (WildPat _) = char '_' pprPat (LazyPat _ pat) = char '~' <> pprParendLPat appPrec pat @@ -591,16 +589,16 @@ pprPat (ConPat { pat_con = con -- error message, and we want to make sure it prints nicely ppr con <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) + , ppr binds ]) <+> pprConArgs details - where ConPatTc { pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds } = ext pprPat (XPat ext) = case ghcPass @p of GhcPs -> noExtCon ext GhcRn -> noExtCon ext - GhcTc -> pprIfTc @p $ pprHsWrapper co $ \parens -> + GhcTc -> pprHsWrapper co $ \parens -> if parens then pprParendPat appPrec pat else pprPat pat @@ -643,24 +641,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) , pat_args = PrefixCon pats , pat_con_ext = ConPatTc - { pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_arg_tys = tys - , pat_wrap = idHsWrapper + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper } } -mkNilPat :: Type -> OutPat (GhcPass p) +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -728,7 +726,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: forall p. (IsPass p, OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -867,11 +865,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat - :: IsPass p - => PprPrec - -> LPat (GhcPass p) - -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -900,7 +897,7 @@ collectEvVarsPat pat = ConPat { pat_args = args , pat_con_ext = ConPatTc - { pat_dicts = dicts + { cpt_dicts = dicts } } -> unionBags (listToBag dicts) ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -91,7 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, - XCollectPat(..), + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -200,12 +200,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam - :: IsPass p - => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) - => [LPat (GhcPass p)] - -> LHsExpr (GhcPass p) - -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -444,38 +443,41 @@ nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs nlInfixConPat con l r = noLoc $ ConPat - (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r)) - noExtField + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs nlConPat con pats = noLoc $ ConPat - (noLoc con) - (PrefixCon (map (parenthesizePat appPrec) pats)) - noExtField + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn nlConPatName con pats = noLoc $ ConPat - (noLoc con) - (PrefixCon (map (parenthesizePat appPrec) pats)) - noExtField - -nlNullaryConPat - :: ( XConPatCon (GhcPass p) ~ IdP (GhcPass p) - , XConPat (GhcPass p) ~ NoExtField - ) - => IdP (GhcPass p) - -> LPat (GhcPass p) -nlNullaryConPat con = noLoc $ ConPat (noLoc con) (PrefixCon []) noExtField + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs nlWildConPat con = noLoc $ ConPat - (noLoc $ getRdrName con) - (PrefixCon $ + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ replicate (dataConSourceArity con) - nlWildPat) - noExtField + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -897,14 +899,12 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch - :: forall p - . IsPass p - => HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] - -> LHsExpr (GhcPass p) - -> Located (HsLocalBinds (GhcPass p)) - -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> Located (HsLocalBinds (GhcPass p)) + -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds = noLoc (Match { m_ext = noExtField , m_ctxt = ctxt @@ -1001,74 +1001,70 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders - :: XCollectPat (GhcPass idL) - => HsLocalBindsLR (GhcPass idL) (GhcPass idR) - -> [IdP (GhcPass idL)] +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] collectLocalBinders (XHsLocalBindsLR _) = [] -collectHsIdBinders, collectHsValBinders - :: XCollectPat (GhcPass idL) - => HsValBindsLR (GhcPass idL) (GhcPass idR) - -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders - :: XCollectPat p - => HsBindLR p idR -> [IdP p] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders - :: XCollectPat p - => LHsBindsLR p idR - -> [IdP p] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders - :: XCollectPat p - => [LHsBindLR p idR] - -> [IdP p] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders - :: XCollectPat (GhcPass idL) - => Bool - -> HsValBindsLR (GhcPass idL) (GhcPass idR) - -> [IdP (GhcPass idL)] +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds - :: XCollectPat p - => Bool - -> [(RecFlag, LHsBinds p)] - -> [IdP p] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds - :: XCollectPat p - => Bool - -> LHsBindsLR p idR - -> [IdP p] - -> [IdP p] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind - :: XCollectPat p - => Bool - -> HsBindLR p idR - -> [IdP p] - -> [IdP p] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1092,25 +1088,24 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: (XCollectPat (GhcPass idL)) +collectLStmtsBinders :: (CollectPass (GhcPass idL)) => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: (XCollectPat (GhcPass idL)) +collectStmtsBinders :: (CollectPass (GhcPass idL)) => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: (XCollectPat (GhcPass idL)) +collectLStmtBinders :: (CollectPass (GhcPass idL)) => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders - :: (XCollectPat (GhcPass idL)) - => StmtLR (GhcPass idL) (GhcPass idR) body - -> [IdP (GhcPass idL)] +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body + -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat collectStmtBinders (LetStmt _ binds) = collectLocalBinders (unLoc binds) @@ -1129,25 +1124,21 @@ collectStmtBinders (XStmtLR nec) = noExtCon nec ----------------- Patterns -------------------------- -collectPatBinders :: XCollectPat p => LPat p -> [IdP p] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: XCollectPat p => [LPat p] -> [IdP p] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat - :: forall pass. - (XCollectPat pass) - => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] collect_lpat p bndrs = collect_pat (unLoc p) bndrs -collect_pat - :: forall p. - XCollectPat p - => Pat p - -> [IdP p] - -> [IdP p] +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] collect_pat pat bndrs = case pat of (VarPat _ var) -> unLoc var : bndrs (WildPat _) -> bndrs @@ -1168,19 +1159,22 @@ collect_pat pat bndrs = case pat of (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) -> collect_pat pat bndrs (SplicePat _ _) -> bndrs - (XPat ext) -> collectPatX (Proxy @p) ext bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs -class (XRec p Pat ~ Located (Pat p)) => XCollectPat p where - collectPatX :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] +-- This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] -instance XCollectPat (GhcPass 'Parsed) where - collectPatX _ ext = noExtCon ext +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext -instance XCollectPat (GhcPass 'Renamed) where - collectPatX _ ext = noExtCon ext +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext -instance XCollectPat (GhcPass 'Typechecked) where - collectPatX _ (CoPat _ pat _) = collect_pat pat +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat {- ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1196,7 +1196,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1237,7 +1237,7 @@ collectl (L _ pat) bndrs go (SumPat _ pat _ _) = collectl pat bndrs go (ConPat { pat_args = ps - , pat_con_ext = ConPatTc { pat_binds = ds }}) = + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,10 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder - :: (XCollectPat (GhcPass p)) - => HsDecl (GhcPass p) - -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -708,11 +708,11 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields pat = noLoc $ ConPat { pat_con = noLoc con , pat_args = PrefixCon $ map nlVarPat arg_ids , pat_con_ext = ConPatTc - { pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap } } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -270,7 +270,7 @@ deListComp (ApplicativeStmt {} : _) _ = deListComp (XStmtLR nec : _) _ = noExtCon nec -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -525,7 +525,7 @@ tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) , pat_args = args , pat_con_ext = ConPatTc - { pat_arg_tys = arg_tys + { cpt_arg_tys = arg_tys } }) -- Newtypes: push bang inwards (#9844) @@ -1124,7 +1124,7 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 patGroup :: Platform -> Pat GhcTc -> PatGroup patGroup _ (ConPat { pat_con = L _ con - , pat_con_ext = ConPatTc { pat_arg_tys = tys } + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -147,9 +147,9 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor { eqn_pats = ConPat { pat_args = args , pat_con_ext = ConPatTc - { pat_tvs = tvs - , pat_dicts = ds - , pat_binds = bind + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind } } : pats })) @@ -181,10 +181,10 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ConPat { pat_con = L _ con1 , pat_args = args1 , pat_con_ext = ConPatTc - { pat_arg_tys = arg_tys - , pat_wrap = wrapper1 - , pat_tvs = tvs1 - , pat_dicts = dicts1 + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 } } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -502,9 +502,9 @@ translatePat fam_insts x pat = case pat of ConPat { pat_con = L _ con , pat_args = ps , pat_con_ext = ConPatTc - { pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts } } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1984,7 +1984,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPat dc details NoExtField) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPat con stuff NoExtField) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -517,7 +517,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPat con' (PrefixCon pats') NoExtField) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +534,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPat con' (RecCon rpats') NoExtField) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Rename/Types.hs ===================================== @@ -1231,27 +1231,46 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPat op1 (InfixCon p11 p12) NoExtField)) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPat op2 (InfixCon p1 p2) NoExtField) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPat op1 (InfixCon p11 (L loc new_p)) NoExtField) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPat op2 (InfixCon p1 p2) NoExtField) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPat op (InfixCon p1 p2) NoExtField) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPat _ (InfixCon _ _) NoExtField) = False +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False not_op_pat _ = True -------------------------------------- @@ -1281,7 +1300,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) checkPrecMatch _ (XMatchGroup nec) = noExtCon nec checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPat op1 (InfixCon _ _) NoExtField) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1270,13 +1270,21 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPat s' (PrefixCon pps) NoExtField } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPat s' - (InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2')) - NoExtField + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] @@ -1290,9 +1298,11 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPat c' - (Hs.RecCon $ HsRecFields fs' Nothing) - NoExtField + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return @@ -1323,7 +1333,11 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return $ ConPat op' (InfixCon x y') NoExtField + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } } ----------------------------------------------------------- ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -603,7 +603,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPat ln@(L _ name) details NoExtField)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1077,7 +1077,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPat (L l c) (PrefixCon args) NoExtField)) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1114,7 +1118,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPat (L cl c) (InfixCon l r) NoExtField) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2065,7 +2073,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return $ PatBuilderPat $ ConPat c (RecCon (HsRecFields fs dd)) NoExtField + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== compiler/typecheck/TcArrows.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/typecheck/TcBinds.hs ===================================== @@ -505,7 +505,7 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - (OutputableBndrId p, XCollectPat (GhcPass p)) + (OutputableBndrId p, CollectPass (GhcPass p)) => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) ===================================== compiler/typecheck/TcGenDeriv.hs ===================================== @@ -534,10 +534,12 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) nlConWildPat con = noLoc $ ConPat - (noLoc $ getRdrName con) - (RecCon $ HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }) - NoExtField + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/typecheck/TcHsSyn.hs ===================================== @@ -118,7 +118,7 @@ hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys hsPatType (SumPat tys _ _ _ ) = mkSumTy tys hsPatType (ConPat { pat_con = lcon , pat_con_ext = ConPatTc - { pat_arg_tys = tys + { cpt_arg_tys = tys } }) = conLikeResTy (unLoc lcon) tys @@ -1309,7 +1309,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1374,11 +1374,11 @@ zonk_pat env (SumPat tys pat alt arity ) zonk_pat env p@(ConPat { pat_con = L _ con , pat_args = args , pat_con_ext = p'@(ConPatTc - { pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_wrap = wrapper - , pat_arg_tys = tys + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys }) }) = ASSERT( all isImmutableTyVar tyvars ) @@ -1404,11 +1404,11 @@ zonk_pat env p@(ConPat { pat_con = L _ con , p { pat_args = new_args , pat_con_ext = p' - { pat_arg_tys = new_tys - , pat_tvs = new_tyvars - , pat_dicts = new_evs - , pat_binds = new_binds - , pat_wrap = new_wrapper + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper } } ) @@ -1454,9 +1454,9 @@ zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1475,7 +1475,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/typecheck/TcPat.hs ===================================== @@ -495,7 +495,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPat con arg_pats NoExtField) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -789,10 +789,10 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty ; let res_pat = ConPat { pat_con = header , pat_args = arg_pats' , pat_con_ext = ConPatTc - { pat_tvs = [], pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_arg_tys = ctxt_res_tys - , pat_wrap = idHsWrapper + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper } } @@ -827,11 +827,11 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty { pat_con = header , pat_args = arg_pats' , pat_con_ext = ConPatTc - { pat_tvs = ex_tvs' - , pat_dicts = given - , pat_binds = ev_binds - , pat_arg_tys = ctxt_res_tys - , pat_wrap = idHsWrapper + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper } } ; return (mkHsWrapPat wrap res_pat pat_ty, res) @@ -881,11 +881,11 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn , pat_args = arg_pats' , pat_con_ext = ConPatTc - { pat_tvs = ex_tvs' - , pat_dicts = prov_dicts' - , pat_binds = ev_binds - , pat_arg_tys = mkTyVarTys univ_tvs' - , pat_wrap = req_wrap + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap } } ; pat_ty <- readExpType pat_ty ===================================== compiler/typecheck/TcPatSyn.hs ===================================== @@ -942,7 +942,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPat con info NoExtField) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -1127,7 +1127,7 @@ tcCollectEx pat = go pat go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p go1 con at ConPat{ pat_con_ext = con' } - = merge (pat_tvs con', pat_dicts con') $ + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p go1 (XPat (CoPat _ p _)) = go1 p ===================================== compiler/typecheck/TcTyClsDecls.hs ===================================== @@ -2195,9 +2195,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2234,8 +2234,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/typecheck/TcTyDecls.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPat (L loc (getName con)) (RecCon rec_fields) NoExtField + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/typecheck/TcValidity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 46c0d63c0a910a34eb307807ea603ad6728b756c +Subproject commit 6809c3cc93193c049f296510a1561941b0a92a5e View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/63e007f1f82fb934b2a68a4e39a92cded56523b7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/63e007f1f82fb934b2a68a4e39a92cded56523b7 You're receiving 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 8 19:44:38 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 08 Apr 2020 15:44:38 -0400 Subject: [Git][ghc/ghc][wip/smaller-coreView] Special case `isConstraintKindCon` on `AlgTyCon` Message-ID: <5e8e29a6d2c8f_616713503ee038122e4@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/smaller-coreView at Glasgow Haskell Compiler / GHC Commits: e7bf529f by Sebastian Graf at 2020-04-08T21:44:30+02:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. - - - - - 3 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/prelude/TysWiredIn.hs Changes: ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -45,7 +45,7 @@ module GHC.Core.TyCon( noTcTyConScopedTyVars, -- ** Predicates on TyCons - isAlgTyCon, isVanillaAlgTyCon, + isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon, isClassTyCon, isFamInstTyCon, isFunTyCon, isPrimTyCon, @@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False +-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind. +isConstraintKindCon :: TyCon -> Bool +-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is +-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector +-- for 'tyConUnique' would generate unreachable code for every other data +-- constructor of TyCon (see #18026). +isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey +isConstraintKindCon _ = False + isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except during type inference. -} -isConstraintKindCon :: TyCon -> Bool -isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey - -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). -- E.g. True of TYPE k, TYPE (F Int) ===================================== compiler/prelude/TysWiredIn.hs ===================================== @@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon typeSymbolKind = mkTyConTy typeSymbolKindCon constraintKindTyCon :: TyCon +-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon! constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e7bf529f05ea7639d66c710f4d4b5feb90e3784c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e7bf529f05ea7639d66c710f4d4b5feb90e3784c You're receiving 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 8 19:59:12 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 08 Apr 2020 15:59:12 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/dmdanal-datacon-sig Message-ID: <5e8e2d10a2a18_61673f8199536d943814819@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/dmdanal-datacon-sig at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/dmdanal-datacon-sig You're receiving 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 8 20:33:23 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 08 Apr 2020 16:33:23 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-datacon-sig] DmdAnal: No need to attach a StrictSig to DataCon workers Message-ID: <5e8e351313db8_61673f81ef22dee43830043@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-datacon-sig at Glasgow Haskell Compiler / GHC Commits: 594163c5 by Sebastian Graf at 2020-04-08T22:33:07+02:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 5 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -614,7 +614,7 @@ data DataConRep -- and *including* all evidence args , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make + -- 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 @@ -715,8 +715,26 @@ filterEqSpec eq_spec instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- 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,Int) +Why? Because the *wrapper* $WMkT is strict (and its unfolding has case +expressions that do the evals) but the *worker* MkT itself is not. If we +pretend it is strict then when we see + case x of y -> MkT y +the simplifier thinks that y is "sure to be evaluated" (because the worker MkT +is strict) and drops the case. No, the workerId MkT is not strict. + +However, the worker does have StrictnessMarks. When the simplifier sees a +pattern + case e of MkT x -> ... +it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's +fine... dataConRepStrictness comes from the data con not from the worker Id. + +Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment dmdTransform env var dmd | isDataConWorkId var -- Data constructor - = dmdTransformDataConSig (idArity var) (idStrictness var) dmd + = dmdTransformDataConSig (idArity var) dmd | gopt Opt_DmdTxDictSel (ae_dflags env), Just _ <- isClassOpId_maybe var -- Dictionary component selector ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -2758,7 +2758,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.Types.Id.Make +See Note [Data-con worker strictness] in GHC.Core.DataCon NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd = postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty -- see Note [Demands from unsaturated function calls] -dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType +dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType -- Same as dmdTransformSig but for a data constructor (worker), -- which has a special kind of demand transformer. -- If the constructor is saturated, we feed the demand on -- the result into the constructor arguments. -dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res)) - (JD { sd = str, ud = abs }) +dmdTransformDataConSig arity (JD { sd = str, ud = abs }) | Just str_dmds <- go_str arity str , Just abs_dmds <- go_abs arity abs - = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res - -- Must remember whether it's a product, hence con_res, not TopRes + = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv | otherwise -- Not saturated = nopDmdType ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con tycon = dataConTyCon data_con -- The representation TyCon wkr_ty = dataConRepType data_con - ----------- Workers for data types -------------- + ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo `setArityInfo` wkr_arity - `setStrictnessInfo` wkr_sig `setCprInfo` mkCprSig wkr_arity (dataConCPR data_con) `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 @@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con -- setNeverLevPoly wkr_arity = dataConRepArity data_con - wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv - -- 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,Int) - -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has - -- case expressions that do the evals) but the *worker* MkT itself is - -- not. If we pretend it is strict then when we see - -- case x of y -> MkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- the worker MkT is strict) and drops the case. No, the workerId - -- MkT is not strict. - -- - -- However, the worker does have StrictnessMarks. When the simplifier - -- sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - ----------- Workers for newtypes -------------- + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/594163c5968e086cc18ef7e1aa36693fb7947a6f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/594163c5968e086cc18ef7e1aa36693fb7947a6f You're receiving 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 8 20:43:17 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 08 Apr 2020 16:43:17 -0400 Subject: [Git][ghc/ghc][master] Make NoExtCon fields strict Message-ID: <5e8e3765e1b2a_616776d1c743841788@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 30 changed files: - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Foreign/Decl.hs - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Fixity.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04b6cf947ea065a210a216cc91f918cc1660d430 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04b6cf947ea065a210a216cc91f918cc1660d430 You're receiving 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 8 20:43:55 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 08 Apr 2020 16:43:55 -0400 Subject: [Git][ghc/ghc][master] Handle promoted data constructors in typeToLHsType correctly Message-ID: <5e8e378b49d4d_61673f81ef22dee438462aa@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - 4 changed files: - compiler/GHC/Hs/Utils.hs - testsuite/tests/deriving/should_compile/T14578.stderr - testsuite/tests/deriving/should_compile/T14579.stderr - testsuite/tests/deriving/should_fail/T15073.stderr Changes: ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -113,6 +113,7 @@ import GHC.Tc.Types.Evidence import GHC.Types.Name.Reader import GHC.Types.Var import GHC.Core.TyCo.Rep +import GHC.Core.TyCon import GHC.Core.Type ( appTyArgFlags, splitAppTys, tyConArgFlags, tyConAppNeedsKindSig ) import TysWiredIn ( unitTy ) import GHC.Tc.Utils.TcType @@ -686,7 +687,11 @@ typeToLHsType ty | otherwise = ty' where ty' :: LHsType GhcPs - ty' = go_app (nlHsTyVar (getRdrName tc)) args (tyConArgFlags tc args) + ty' = go_app (noLoc $ HsTyVar noExtField prom $ noLoc $ getRdrName tc) + args (tyConArgFlags tc args) + + prom :: PromotionFlag + prom = if isPromotedDataCon tc then IsPromoted else NotPromoted go ty@(AppTy {}) = go_app (go head) args (appTyArgFlags head args) where head :: Type ===================================== testsuite/tests/deriving/should_compile/T14578.stderr ===================================== @@ -9,7 +9,7 @@ Derived class instances: GHC.Base.sconcat :: GHC.Base.NonEmpty (T14578.Wat f g a) -> T14578.Wat f g a GHC.Base.stimes :: - forall (b :: TYPE GHC.Types.LiftedRep). + forall (b :: TYPE 'GHC.Types.LiftedRep). GHC.Real.Integral b => b -> T14578.Wat f g a -> T14578.Wat f g a (GHC.Base.<>) = GHC.Prim.coerce @@ -37,12 +37,12 @@ Derived class instances: instance GHC.Base.Functor f => GHC.Base.Functor (T14578.App f) where GHC.Base.fmap :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). (a -> b) -> T14578.App f a -> T14578.App f b (GHC.Base.<$) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). a -> T14578.App f b -> T14578.App f a GHC.Base.fmap = GHC.Prim.coerce @@ -56,23 +56,23 @@ Derived class instances: instance GHC.Base.Applicative f => GHC.Base.Applicative (T14578.App f) where GHC.Base.pure :: - forall (a :: TYPE GHC.Types.LiftedRep). a -> T14578.App f a + forall (a :: TYPE 'GHC.Types.LiftedRep). a -> T14578.App f a (GHC.Base.<*>) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). T14578.App f (a -> b) -> T14578.App f a -> T14578.App f b GHC.Base.liftA2 :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep) - (c :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep) + (c :: TYPE 'GHC.Types.LiftedRep). (a -> b -> c) -> T14578.App f a -> T14578.App f b -> T14578.App f c (GHC.Base.*>) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). T14578.App f a -> T14578.App f b -> T14578.App f b (GHC.Base.<*) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). T14578.App f a -> T14578.App f b -> T14578.App f a GHC.Base.pure = GHC.Prim.coerce ===================================== testsuite/tests/deriving/should_compile/T14579.stderr ===================================== @@ -8,16 +8,16 @@ Derived class instances: T14579.Glurp a -> T14579.Glurp a -> GHC.Types.Bool (GHC.Classes.==) = GHC.Prim.coerce - @(T14579.Wat @a (Data.Proxy.Proxy @a) - -> T14579.Wat @a (Data.Proxy.Proxy @a) -> GHC.Types.Bool) + @(T14579.Wat @a ('Data.Proxy.Proxy @a) + -> T14579.Wat @a ('Data.Proxy.Proxy @a) -> GHC.Types.Bool) @(T14579.Glurp a -> T14579.Glurp a -> GHC.Types.Bool) - ((GHC.Classes.==) @(T14579.Wat @a (Data.Proxy.Proxy @a))) + ((GHC.Classes.==) @(T14579.Wat @a ('Data.Proxy.Proxy @a))) (GHC.Classes./=) = GHC.Prim.coerce - @(T14579.Wat @a (Data.Proxy.Proxy @a) - -> T14579.Wat @a (Data.Proxy.Proxy @a) -> GHC.Types.Bool) + @(T14579.Wat @a ('Data.Proxy.Proxy @a) + -> T14579.Wat @a ('Data.Proxy.Proxy @a) -> GHC.Types.Bool) @(T14579.Glurp a -> T14579.Glurp a -> GHC.Types.Bool) - ((GHC.Classes./=) @(T14579.Wat @a (Data.Proxy.Proxy @a))) + ((GHC.Classes./=) @(T14579.Wat @a ('Data.Proxy.Proxy @a))) instance forall a (x :: Data.Proxy.Proxy a). GHC.Classes.Eq a => ===================================== testsuite/tests/deriving/should_fail/T15073.stderr ===================================== @@ -3,7 +3,7 @@ T15073.hs:8:12: error: • Illegal unboxed tuple type as function argument: (# Foo a #) Perhaps you intended to use UnboxedTuples • In the type signature: - p :: Foo a -> Unit# @GHC.Types.LiftedRep (Foo a) + p :: Foo a -> Unit# @'GHC.Types.LiftedRep (Foo a) When typechecking the code for ‘p’ in a derived instance for ‘P (Foo a)’: To see the code I am typechecking, use -ddump-deriv View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7802fa17a9a1a0f02fbf95170c13d7a9711a681e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7802fa17a9a1a0f02fbf95170c13d7a9711a681e You're receiving 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 8 22:09:06 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 08 Apr 2020 18:09:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17173 Message-ID: <5e8e4b822f583_61677c82e0c3852780@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T17173 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17173 You're receiving 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 8 23:55:16 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 08 Apr 2020 19:55:16 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] Inline expandSynTyCon_maybe Message-ID: <5e8e6464636bd_6167136dfb9c3909011@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: fae67360 by Ben Gamari at 2020-04-08T19:54:43-04:00 Inline expandSynTyCon_maybe This is necessary to avoid some needless allocation since we currently lack nested CPR on sums. Metric Decrease: T12227 T12545 T12707 T14683 T3064 T5631 T5642 T9020 T9872a - - - - - 1 changed file: - compiler/GHC/Core/TyCon.hs Changes: ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -2296,6 +2296,9 @@ expandSynTyCon_maybe tc tys LT -> Nothing | otherwise = Nothing +{-# INLINE expandSynTyCon_maybe #-} +-- Inline to avoid allocation of tuples due to lack of nested CPR on sums. +-- Particularly relevant to coreView and tcView, which are hammered. ---------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fae673605c27db4ece0825ff533a7dcd4f32312d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fae673605c27db4ece0825ff533a7dcd4f32312d You're receiving 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 9 01:16:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 08 Apr 2020 21:16:42 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Handle promoted data constructors in typeToLHsType correctly Message-ID: <5e8e777a31bb7_6167134ebbc439176d7@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - 6f5d3937 by Ben Gamari at 2020-04-08T21:16:29-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - 46345c33 by Ben Gamari at 2020-04-08T21:16:29-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - e8e100ea by Sylvain Henry at 2020-04-08T21:16:34-04:00 Rts: show errno on failure (#18033) - - - - - 7 changed files: - compiler/GHC/Hs/Utils.hs - hadrian/src/Settings/Packages.hs - rts/posix/itimer/Pthread.c - testsuite/tests/deriving/should_compile/T14578.stderr - testsuite/tests/deriving/should_compile/T14579.stderr - testsuite/tests/deriving/should_fail/T15073.stderr - utils/iserv/ghc.mk Changes: ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -113,6 +113,7 @@ import GHC.Tc.Types.Evidence import GHC.Types.Name.Reader import GHC.Types.Var import GHC.Core.TyCo.Rep +import GHC.Core.TyCon import GHC.Core.Type ( appTyArgFlags, splitAppTys, tyConArgFlags, tyConAppNeedsKindSig ) import TysWiredIn ( unitTy ) import GHC.Tc.Utils.TcType @@ -686,7 +687,11 @@ typeToLHsType ty | otherwise = ty' where ty' :: LHsType GhcPs - ty' = go_app (nlHsTyVar (getRdrName tc)) args (tyConArgFlags tc args) + ty' = go_app (noLoc $ HsTyVar noExtField prom $ noLoc $ getRdrName tc) + args (tyConArgFlags tc args) + + prom :: PromotionFlag + prom = if isPromotedDataCon tc then IsPromoted else NotPromoted go ty@(AppTy {}) = go_app (go head) args (appTyArgFlags head args) where head :: Type ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -122,6 +122,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , cross ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -110,13 +110,13 @@ static void *itimer_thread_func(void *_handle_tick) timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { - barf("timerfd_create"); + barf("timerfd_create: %s", strerror(errno)); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { - barf("timerfd_settime"); + barf("timerfd_settime: %s", strerror(errno)); } #endif @@ -124,7 +124,7 @@ static void *itimer_thread_func(void *_handle_tick) if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); + barf("Itimer: read(timerfd) failed: %s", strerror(errno)); } } } else { @@ -170,7 +170,7 @@ initTicker (Time interval, TickProc handle_tick) pthread_setname_np(thread, "ghc_ticker"); #endif } else { - barf("Itimer: Failed to spawn thread"); + barf("Itimer: Failed to spawn thread: %s", strerror(errno)); } } @@ -204,7 +204,7 @@ exitTicker (bool wait) // wait for ticker to terminate if necessary if (wait) { if (pthread_join(thread, NULL)) { - sysErrorBelch("Itimer: Failed to join"); + sysErrorBelch("Itimer: Failed to join: %s", strerror(errno)); } closeMutex(&mutex); closeCondition(&start_cond); ===================================== testsuite/tests/deriving/should_compile/T14578.stderr ===================================== @@ -9,7 +9,7 @@ Derived class instances: GHC.Base.sconcat :: GHC.Base.NonEmpty (T14578.Wat f g a) -> T14578.Wat f g a GHC.Base.stimes :: - forall (b :: TYPE GHC.Types.LiftedRep). + forall (b :: TYPE 'GHC.Types.LiftedRep). GHC.Real.Integral b => b -> T14578.Wat f g a -> T14578.Wat f g a (GHC.Base.<>) = GHC.Prim.coerce @@ -37,12 +37,12 @@ Derived class instances: instance GHC.Base.Functor f => GHC.Base.Functor (T14578.App f) where GHC.Base.fmap :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). (a -> b) -> T14578.App f a -> T14578.App f b (GHC.Base.<$) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). a -> T14578.App f b -> T14578.App f a GHC.Base.fmap = GHC.Prim.coerce @@ -56,23 +56,23 @@ Derived class instances: instance GHC.Base.Applicative f => GHC.Base.Applicative (T14578.App f) where GHC.Base.pure :: - forall (a :: TYPE GHC.Types.LiftedRep). a -> T14578.App f a + forall (a :: TYPE 'GHC.Types.LiftedRep). a -> T14578.App f a (GHC.Base.<*>) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). T14578.App f (a -> b) -> T14578.App f a -> T14578.App f b GHC.Base.liftA2 :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep) - (c :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep) + (c :: TYPE 'GHC.Types.LiftedRep). (a -> b -> c) -> T14578.App f a -> T14578.App f b -> T14578.App f c (GHC.Base.*>) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). T14578.App f a -> T14578.App f b -> T14578.App f b (GHC.Base.<*) :: - forall (a :: TYPE GHC.Types.LiftedRep) - (b :: TYPE GHC.Types.LiftedRep). + forall (a :: TYPE 'GHC.Types.LiftedRep) + (b :: TYPE 'GHC.Types.LiftedRep). T14578.App f a -> T14578.App f b -> T14578.App f a GHC.Base.pure = GHC.Prim.coerce ===================================== testsuite/tests/deriving/should_compile/T14579.stderr ===================================== @@ -8,16 +8,16 @@ Derived class instances: T14579.Glurp a -> T14579.Glurp a -> GHC.Types.Bool (GHC.Classes.==) = GHC.Prim.coerce - @(T14579.Wat @a (Data.Proxy.Proxy @a) - -> T14579.Wat @a (Data.Proxy.Proxy @a) -> GHC.Types.Bool) + @(T14579.Wat @a ('Data.Proxy.Proxy @a) + -> T14579.Wat @a ('Data.Proxy.Proxy @a) -> GHC.Types.Bool) @(T14579.Glurp a -> T14579.Glurp a -> GHC.Types.Bool) - ((GHC.Classes.==) @(T14579.Wat @a (Data.Proxy.Proxy @a))) + ((GHC.Classes.==) @(T14579.Wat @a ('Data.Proxy.Proxy @a))) (GHC.Classes./=) = GHC.Prim.coerce - @(T14579.Wat @a (Data.Proxy.Proxy @a) - -> T14579.Wat @a (Data.Proxy.Proxy @a) -> GHC.Types.Bool) + @(T14579.Wat @a ('Data.Proxy.Proxy @a) + -> T14579.Wat @a ('Data.Proxy.Proxy @a) -> GHC.Types.Bool) @(T14579.Glurp a -> T14579.Glurp a -> GHC.Types.Bool) - ((GHC.Classes./=) @(T14579.Wat @a (Data.Proxy.Proxy @a))) + ((GHC.Classes./=) @(T14579.Wat @a ('Data.Proxy.Proxy @a))) instance forall a (x :: Data.Proxy.Proxy a). GHC.Classes.Eq a => ===================================== testsuite/tests/deriving/should_fail/T15073.stderr ===================================== @@ -3,7 +3,7 @@ T15073.hs:8:12: error: • Illegal unboxed tuple type as function argument: (# Foo a #) Perhaps you intended to use UnboxedTuples • In the type signature: - p :: Foo a -> Unit# @GHC.Types.LiftedRep (Foo a) + p :: Foo a -> Unit# @'GHC.Types.LiftedRep (Foo a) When typechecking the code for ‘p’ in a derived instance for ‘P (Foo a)’: To see the code I am typechecking, use -ddump-deriv ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ff8d3604b3dc946f968347aa524a4436efee18d...e8e100ead0c5d8c7d12ae3079ed6f5f0307ed073 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ff8d3604b3dc946f968347aa524a4436efee18d...e8e100ead0c5d8c7d12ae3079ed6f5f0307ed073 You're receiving 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 9 04:15:29 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 09 Apr 2020 00:15:29 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] Some cleanup Message-ID: <5e8ea161e07a7_6167136dfb9c39223aa@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: 0038463c by Ben Gamari at 2020-04-09T00:15:14-04:00 Some cleanup - - - - - 6 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/prelude/TysPrim.hs - compiler/typecheck/TcCanonical.hs - compiler/typecheck/TcType.hs Changes: ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -2289,16 +2289,13 @@ expandSynTyCon_maybe expandSynTyCon_maybe tc tys | SynonymTyCon { tyConTyVars = tvs, synTcRhs = rhs, tyConArity = arity } <- tc = case tys of - [] -> Just ([], rhs, tys) + [] -> Just ([], rhs, []) -- Avoid a bit of work in the case of nullary synonyms _ -> case tys `listLengthCmp` arity of GT -> Just (tvs `zip` tys, rhs, drop arity tys) EQ -> Just (tvs `zip` tys, rhs, []) LT -> Nothing | otherwise = Nothing -{-# INLINE expandSynTyCon_maybe #-} --- Inline to avoid allocation of tuples due to lack of nested CPR on sums. --- Particularly relevant to coreView and tcView, which are hammered. ---------------- ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -350,18 +350,16 @@ See also #11715, which tracks removing this inconsistency. -} -- | Gives the typechecker view of a type. This unwraps synonyms but --- leaves 'Constraint' alone. c.f. coreView, which turns Constraint into --- TYPE LiftedRep. Returns Nothing if no unwrapping happens. +-- leaves 'Constraint' alone. c.f. 'coreView', which turns 'Constraint' into +-- @TYPE LiftedRep at . Returns 'Nothing' if no unwrapping happens. -- See also Note [coreView vs tcView] {-# INLINE tcView #-} tcView :: Type -> Maybe Type tcView (TyConApp tc tys) - | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys - = Just $ case tenv of - [] -> mkAppTys rhs tys' - _ -> mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys' + | res@(Just _) <- expandSynTyConApp_maybe tc tys + = res -- The free vars of 'rhs' should all be bound by 'tenv', so it's - -- ok to use 'substTy' here. + -- ok to use 'substTy' here (which is what expandSynTyConApp_maybe does). -- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst. -- Its important to use mkAppTys, rather than (foldl AppTy), -- because the function part might well return a @@ -370,19 +368,16 @@ tcView _ = Nothing {-# INLINE coreView #-} coreView :: Type -> Maybe Type --- ^ This function Strips off the /top layer only/ of a type synonym +-- ^ This function strips off the /top layer only/ of a type synonym -- application (if any) its underlying representation type. --- Returns Nothing if there is nothing to look through. +-- Returns 'Nothing' if there is nothing to look through. -- This function considers 'Constraint' to be a synonym of @TYPE LiftedRep at . -- -- By being non-recursive and inlined, this case analysis gets efficiently -- joined onto the case analysis that the caller is already doing coreView ty@(TyConApp tc tys) - | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys - = Just $ case tenv of - [] -> mkAppTys rhs tys' - _ -> mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys' - -- This equation is exactly like tcView + | res@(Just _) <- expandSynTyConApp_maybe tc tys + = res -- At the Core level, Constraint = Type -- See Note [coreView vs tcView] @@ -393,6 +388,21 @@ coreView ty@(TyConApp tc tys) coreView _ = Nothing ----------------------------------------------- +expandSynTyConApp_maybe :: TyCon -> [Type] -> Maybe Type +expandSynTyConApp_maybe tc tys + | Just (tvs, rhs) <- synTyConDefn_maybe tc + = case tys of + [] -> Just (mkAppTys rhs tys) + _ -> case tys `listLengthCmp` arity of + GT -> Just (mkAppTys rhs' (drop arity tys)) + EQ -> Just rhs' + LT -> Nothing + where + arity = tyConArity tc + rhs' = substTy (mkTvSubstPrs (tvs `zip` tys)) rhs + | otherwise + = Nothing + expandTypeSynonyms :: Type -> Type -- ^ Expand out all type synonyms. Actually, it'd suffice to expand out -- just the ones that discard type variables (e.g. type Funny a = Int) @@ -1223,8 +1233,10 @@ TyConApp constructors were all duplicates of `Type` applied to no arguments. Therefore in `mkTyConApp` we have a special case for `Type` to ensure that only one `TyConApp 'Type []` closure is allocated during the course of -compilation. In order to avoid a potentially expensive series of checks in -`mkTyConApp` only this egregious case is special cased at the moment. +compilation. + +We also have a similar special-case for applications of TYPE; see +Note [Prefer Type over TYPE 'LiftedPtrRep] for details. --------------------------------------------------------------------- @@ -1236,7 +1248,6 @@ compilation. In order to avoid a potentially expensive series of checks in -- its arguments. Applies its arguments to the constructor from left to right. mkTyConApp :: TyCon -> [Type] -> Type mkTyConApp tycon tys --- TODO: TYPE 'LiftedRep | isFunTyCon tycon , [_rep1,_rep2,ty1,ty2] <- tys -- The FunTyCon (->) is always a visible one @@ -1245,7 +1256,7 @@ mkTyConApp tycon tys | tycon == liftedTypeKindTyCon = ASSERT2( null tys, ppr tycon $$ ppr tys ) liftedTypeKindTyConApp - -- Note [mkTyConApp and Type] + -- Note [Prefer Type over TYPE 'LiftedPtrRep] | tycon == tYPETyCon , [rep] <- tys = tYPE rep @@ -2203,6 +2214,36 @@ But the left is an AppTy while the right is a TyConApp. The solution is to use repSplitAppTy_maybe to break up the TyConApp into its pieces and then continue. Easy to do, but also easy to forget to do. + +Note [Comparing nullary type synonyms] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the task of testing equality between two 'Type's of the form + + TyConApp tc [] + +where @tc@ is a type synonym. A naive way to perform this comparison these +would first expand the synonym and then compare the resulting expansions. + +However, this is obviously wasteful and the RHS of @tc@ may be large; it is +much better to rather compare the TyCons directly. Consequently, before +expanding type synonyms in type comparisons we first look for a nullary +TyConApp and simply compare the TyCons if we find one. Of course, if we find +that the TyCons are *not* equal then we still need to perform the expansion as +their RHSs may still be equal. + +We perform this optimisation in a number of places: + + * GHC.Core.Types.eqType + * GHC.Core.Types.nonDetCmpType + * GHC.Core.Unify.unify_ty + * TcCanonical.can_eq_nc' + * TcUnify.uType + +This optimisation is especially helpful for the ubiquitous GHC.Types.Type, +since GHC prefers to use the type synonym over @TYPE 'LiftedPtr@ applications +whenever possible. See [Prefer Type over TYPE 'LiftedPtrRep] in TysPrim for +details. + -} eqType :: Type -> Type -> Bool @@ -2276,7 +2317,6 @@ data TypeOrdering = TLT -- ^ @t1 < t2@ | TGT -- ^ @t1 > t2@ deriving (Eq, Ord, Enum, Bounded) --- TODO: nullary synonym optimization nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering -- Main workhorse -- See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep nonDetCmpTypeX env orig_t1 orig_t2 = ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -957,7 +957,7 @@ unify_ty :: UMEnv -- Respects newtypes, PredTypes unify_ty env ty1 ty2 kco - -- See Note [Comparing nullary type synonyms]. + -- See Note [Comparing nullary type synonyms] in GHC.Core.Type. | TyConApp tc1 [] <- ty1 , TyConApp tc2 [] <- ty2 , tc1 == tc2 = return () ===================================== compiler/prelude/TysPrim.hs ===================================== @@ -527,11 +527,35 @@ mkPrimTcName built_in_syntax occ key tycon -- | Given a RuntimeRep, applies TYPE to it. -- see Note [TYPE and RuntimeRep] tYPE :: Type -> Type - -- static cases tYPE (TyConApp tc []) | tc `hasKey` liftedRepDataConKey = liftedTypeKind -- TYPE 'LiftedPtrRep tYPE rr = TyConApp tYPETyCon [rr] +-- Note [Prefer Type over TYPE 'LiftedPtrRep] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- The Core of nearly any program will have numerous occurrences of +-- @TYPE 'LiftedPtrRep@ floating about. Consequently, we try hard to ensure +-- that operations on such types are efficient: +-- +-- * Instead of representing the lifted kind as +-- @TyConApp tYPETyCon [liftedRepDataCon]@ we rather prefer to +-- use the 'GHC.Types.Type' type synonym (available in GHC as +-- 'TysPrim.liftedTypeKind'). Note only is this a smaller AST but it also +-- guarantees sharing on the heap. +-- +-- * To avoid allocating 'TyConApp' constructors 'TysPrim.tYPE' +-- catches the lifted case and uses `liftedTypeKind` instead of building an +-- application. +-- +-- * Similarly, 'Type.mkTyConApp' catches applications of TYPE and +-- handles them using 'TysPrim.tYPE', ensuring that it benefits from the +-- optimisation described above. +-- +-- * Since 'liftedTypeKind' is a nullary type synonym application, +-- it benefits from the optimisation described in Note [Comparing nullary +-- type synonyms] in "GHC.Core.Type". + {- ************************************************************************ * * ===================================== compiler/typecheck/TcCanonical.hs ===================================== @@ -969,14 +969,13 @@ can_eq_nc' -> Type -> Type -- RHS, after and before type-synonym expansion, resp -> TcS (StopOrContinue Ct) --- See Note [Comparing nullary type synonyms]. +-- See Note [Comparing nullary type synonyms] in GHC.Core.Type. can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1@(TyConApp tc1 []) _ps_ty1 (TyConApp tc2 []) _ps_ty2 | tc1 == tc2 = canEqReflexive ev eq_rel ty1 -- Expand synonyms first; see Note [Type synonyms and canonicalization] can_eq_nc' flat rdr_env envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2 --- TODO: Handle nullary synonyms | Just ty1' <- tcView ty1 = can_eq_nc' flat rdr_env envs ev eq_rel ty1' ps_ty1 ty2 ps_ty2 | Just ty2' <- tcView ty2 = can_eq_nc' flat rdr_env envs ev eq_rel ty1 ps_ty1 ty2' ps_ty2 ===================================== compiler/typecheck/TcType.hs ===================================== @@ -1533,7 +1533,7 @@ tc_eq_type keep_syns vis_only orig_ty1 orig_ty2 = go orig_env orig_ty1 orig_ty2 where go :: RnEnv2 -> Type -> Type -> Bool - -- See Note [Comparing nullary type synonyms]. + -- See Note [Comparing nullary type synonyms] in GHC.Core.Type. go _ (TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2 = True @@ -1570,7 +1570,6 @@ tc_eq_type keep_syns vis_only orig_ty1 orig_ty2 = go env s1 s2 && go env t1 t2 go env (TyConApp tc1 ts1) (TyConApp tc2 ts2) - -- TODO: nullary synonym optimisation = tc1 == tc2 && gos env (tc_vis tc1) ts1 ts2 go env (CastTy t1 _) t2 = go env t1 t2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0038463cb7070090b9e62f0c5278a8f8f47ac7df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0038463cb7070090b9e62f0c5278a8f8f47ac7df You're receiving 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 9 08:37:22 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 09 Apr 2020 04:37:22 -0400 Subject: [Git][ghc/ghc][wip/smaller-coreView] Special case `isConstraintKindCon` on `AlgTyCon` Message-ID: <5e8edec28d192_6167134ebbc4395211f@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/smaller-coreView at Glasgow Haskell Compiler / GHC Commits: 84f0448c by Sebastian Graf at 2020-04-09T10:36:57+02:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - 3 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/prelude/TysWiredIn.hs Changes: ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -45,7 +45,7 @@ module GHC.Core.TyCon( noTcTyConScopedTyVars, -- ** Predicates on TyCons - isAlgTyCon, isVanillaAlgTyCon, + isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon, isClassTyCon, isFamInstTyCon, isFunTyCon, isPrimTyCon, @@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False +-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind. +isConstraintKindCon :: TyCon -> Bool +-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is +-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector +-- for 'tyConUnique' would generate unreachable code for every other data +-- constructor of TyCon (see #18026). +isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey +isConstraintKindCon _ = False + isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except during type inference. -} -isConstraintKindCon :: TyCon -> Bool -isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey - -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). -- E.g. True of TYPE k, TYPE (F Int) ===================================== compiler/prelude/TysWiredIn.hs ===================================== @@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon typeSymbolKind = mkTyConTy typeSymbolKindCon constraintKindTyCon :: TyCon +-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon! constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84f0448c56b4a8b37e34fc1ae6faca20c7c1729c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84f0448c56b4a8b37e34fc1ae6faca20c7c1729c You're receiving 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 9 11:27:58 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 09 Apr 2020 07:27:58 -0400 Subject: [Git][ghc/ghc][wip/andreask/strict_dicts] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5e8f06bef321a_6167e4e49b43976999@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/andreask/strict_dicts at Glasgow Haskell Compiler / GHC Commits: b9ff82fe by Sebastian Graf at 2020-04-09T13:25:17+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. - - - - - 2 changed files: - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs Changes: ===================================== compiler/GHC/Core/Op/SpecConstr.hs ===================================== @@ -1995,7 +1995,7 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Remove ones that have too many worker variables small_pats = filterOut too_big non_dups - too_big (vars,_) = not (isWorkerSmallEnough (sc_dflags env) vars) + too_big (vars,args) = not (isWorkerSmallEnough (sc_dflags env) (length args) vars) -- We are about to construct w/w pair in 'spec_one'. -- Omit specialisation leading to high arity workers. -- See Note [Limit w/w arity] in GHC.Core.Op.WorkWrap.Lib ===================================== compiler/GHC/Core/Op/WorkWrap/Lib.hs ===================================== @@ -162,7 +162,7 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if isWorkerSmallEnough dflags work_args + ; if isWorkerSmallEnough dflags (length demands) work_args && not (too_many_args_for_join_point wrap_args) && ((useful1 && not only_one_void_argument) || useful2) then return (Just (worker_args_dmds, length work_call_args, @@ -203,10 +203,13 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info = False -- See Note [Limit w/w arity] -isWorkerSmallEnough :: DynFlags -> [Var] -> Bool -isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags +isWorkerSmallEnough :: DynFlags -> Int -> [Var] -> Bool +isWorkerSmallEnough dflags old_n_args vars + = count isId vars <= max old_n_args (maxWorkerArgs dflags) -- We count only Free variables (isId) to skip Type, Kind -- variables which have no runtime representation. + -- Also if the function took 82 arguments before (old_n_args), it's fine if + -- it takes <= 82 arguments afterwards. {- Note [Always do CPR w/w] @@ -227,7 +230,8 @@ Guard against high worker arity as it generates a lot of stack traffic. A simplified example is #11565#comment:6 Current strategy is very simple: don't perform w/w transformation at all -if the result produces a wrapper with arity higher than -fmax-worker-args=. +if the result produces a wrapper with arity higher than -fmax-worker-args +and the number arguments before w/w. It is a bit all or nothing, consider View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b9ff82fee1e600ca2c183725c97d2b6e1d59a668 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b9ff82fee1e600ca2c183725c97d2b6e1d59a668 You're receiving 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 9 11:57:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 07:57:15 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: hadrian: Use --export-dynamic when linking iserv Message-ID: <5e8f0d9bbcf35_6167136dfb9c3983119@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6ac47d96 by Ben Gamari at 2020-04-09T07:56:59-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - 7932ee5d by Ben Gamari at 2020-04-09T07:56:59-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - aa69bf1a by Ömer Sinan Ağacan at 2020-04-09T07:57:04-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - 55edd915 by Sylvain Henry at 2020-04-09T07:57:09-04:00 Rts: show errno on failure (#18033) - - - - - 12 changed files: - hadrian/src/Settings/Packages.hs - includes/rts/storage/Closures.h - libraries/ghc-compact/tests/all.T - libraries/ghc-compact/tests/compact_gc.hs - rts/Hash.c - rts/Hash.h - rts/StgMiscClosures.cmm - rts/posix/itimer/Pthread.c - rts/sm/CNF.c - rts/sm/Compact.c - testsuite/config/ghc - utils/iserv/ghc.mk Changes: ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -122,6 +122,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , cross ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== includes/rts/storage/Closures.h ===================================== @@ -486,4 +486,7 @@ typedef struct StgCompactNFData_ { StgClosure *result; // Used temporarily to store the result of compaction. Doesn't need to be // a GC root. + struct StgCompactNFData_ *link; + // Used by compacting GC for linking CNFs with threaded hash tables. See + // Note [CNFs in compacting GC] in Compact.c for details. } StgCompactNFData; ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -1,4 +1,4 @@ -setTestOpts(extra_ways(['sanity'])) +setTestOpts(extra_ways(['sanity', 'compacting_gc'])) test('compact_simple', normal, compile_and_run, ['']) test('compact_loop', normal, compile_and_run, ['']) ===================================== libraries/ghc-compact/tests/compact_gc.hs ===================================== @@ -6,6 +6,8 @@ main = do let m = Map.fromList [(x,show x) | x <- [1..(10000::Int)]] c <- compactWithSharing m print =<< compactSize c - c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c); print =<< compactSize c; return c) c [1..10] + c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c) + print =<< compactSize c + return c) c [1..10] print (length (show (getCompact c))) print =<< compactSize c ===================================== rts/Hash.c ===================================== @@ -444,17 +444,13 @@ freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) void mapHashTable(HashTable *table, void *data, MapHashFn fn) { - long segment; - long index; - HashList *hl; - /* The last bucket with something in it is table->max + table->split - 1 */ - segment = (table->max + table->split - 1) / HSEGSIZE; - index = (table->max + table->split - 1) % HSEGSIZE; + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; while (segment >= 0) { while (index >= 0) { - for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { fn(data, hl->key, hl->data); } index--; @@ -464,6 +460,25 @@ mapHashTable(HashTable *table, void *data, MapHashFn fn) } } +void +mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn) +{ + /* The last bucket with something in it is table->max + table->split - 1 */ + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; + + while (segment >= 0) { + while (index >= 0) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + fn(data, &hl->key, hl->data); + } + index--; + } + segment--; + index = HSEGSIZE - 1; + } +} + /* ----------------------------------------------------------------------------- * When we initialize a hash table, we set up the first segment as well, * initializing all of the first segment's hash buckets to NULL. ===================================== rts/Hash.h ===================================== @@ -34,8 +34,10 @@ int keyCountHashTable (HashTable *table); int keysHashTable(HashTable *table, StgWord keys[], int szKeys); typedef void (*MapHashFn)(void *data, StgWord key, const void *value); +typedef void (*MapHashFnKeys)(void *data, StgWord *key, const void *value); void mapHashTable(HashTable *table, void *data, MapHashFn fn); +void mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn); /* Hash table access where the keys are C strings (the strings are * assumed to be allocated by the caller, and mustn't be deallocated ===================================== rts/StgMiscClosures.cmm ===================================== @@ -686,11 +686,11 @@ INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE compaction is in progress and the hash table needs to be scanned by the GC. ------------------------------------------------------------------------- */ -INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_CLEAN object (%p) entered!", R1) never returns; } -INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1) never returns; } ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -110,13 +110,13 @@ static void *itimer_thread_func(void *_handle_tick) timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { - barf("timerfd_create"); + barf("timerfd_create: %s", strerror(errno)); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { - barf("timerfd_settime"); + barf("timerfd_settime: %s", strerror(errno)); } #endif @@ -124,7 +124,7 @@ static void *itimer_thread_func(void *_handle_tick) if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); + barf("Itimer: read(timerfd) failed: %s", strerror(errno)); } } } else { @@ -170,7 +170,7 @@ initTicker (Time interval, TickProc handle_tick) pthread_setname_np(thread, "ghc_ticker"); #endif } else { - barf("Itimer: Failed to spawn thread"); + barf("Itimer: Failed to spawn thread: %s", strerror(errno)); } } @@ -204,7 +204,7 @@ exitTicker (bool wait) // wait for ticker to terminate if necessary if (wait) { if (pthread_join(thread, NULL)) { - sysErrorBelch("Itimer: Failed to join"); + sysErrorBelch("Itimer: Failed to join: %s", strerror(errno)); } closeMutex(&mutex); closeCondition(&start_cond); ===================================== rts/sm/CNF.c ===================================== @@ -381,6 +381,7 @@ compactNew (Capability *cap, StgWord size) self->nursery = block; self->last = block; self->hash = NULL; + self->link = NULL; block->owner = self; ===================================== rts/sm/Compact.c ===================================== @@ -473,6 +473,67 @@ thread_TSO (StgTSO *tso) return (P_)tso + sizeofW(StgTSO); } +/* ---------------------------------------------------------------------------- + Note [CNFs in compacting GC] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CNF hash table keys point outside of the CNF so those need to be threaded + and updated during compaction. After compaction we need to re-visit those + hash tables for re-hashing. The list `nfdata_chain` is used for that + purpose. When we thread keys of a CNF we add the CNF to the list. After + compacting is done we re-visit the CNFs in the list and re-hash their + tables. See also #17937 for more details. + ------------------------------------------------------------------------- */ + +static StgCompactNFData *nfdata_chain = NULL; + +static void +thread_nfdata_hash_key(void *data STG_UNUSED, StgWord *key, const void *value STG_UNUSED) +{ + thread_((void *)key); +} + +static void +add_hash_entry(void *data, StgWord key, const void *value) +{ + HashTable *new_hash = (HashTable *)data; + insertHashTable(new_hash, key, value); +} + +static void +rehash_CNFs(void) +{ + while (nfdata_chain != NULL) { + StgCompactNFData *str = nfdata_chain; + nfdata_chain = str->link; + str->link = NULL; + + HashTable *new_hash = allocHashTable(); + mapHashTable(str->hash, (void*)new_hash, add_hash_entry); + freeHashTable(str->hash, NULL); + str->hash = new_hash; + } +} + +static void +update_fwd_cnf( bdescr *bd ) +{ + while (bd) { + ASSERT(bd->flags & BF_COMPACT); + StgCompactNFData *str = ((StgCompactNFDataBlock*)bd->start)->owner; + + // Thread hash table keys. Values won't be moved as those are inside the + // CNF, and the CNF is a large object and so won't ever move. + if (str->hash) { + mapHashTableKeys(str->hash, NULL, thread_nfdata_hash_key); + ASSERT(str->link == NULL); + str->link = nfdata_chain; + nfdata_chain = str; + } + + bd = bd->link; + } +} static void update_fwd_large( bdescr *bd ) @@ -489,7 +550,6 @@ update_fwd_large( bdescr *bd ) switch (info->type) { case ARR_WORDS: - case COMPACT_NFDATA: // nothing to follow continue; @@ -968,6 +1028,7 @@ compact(StgClosure *static_objects, update_fwd(gc_threads[n]->gens[g].part_list); } update_fwd_large(gen->scavenged_large_objects); + update_fwd_cnf(gen->live_compact_objects); if (g == RtsFlags.GcFlags.generations-1 && gen->old_blocks != NULL) { debugTrace(DEBUG_gc, "update_fwd: %d (compact)", g); update_fwd_compact(gen->old_blocks); @@ -983,4 +1044,8 @@ compact(StgClosure *static_objects, gen->no, gen->n_old_blocks, blocks); gen->n_old_blocks = blocks; } + + // 4. Re-hash hash tables of threaded CNFs. + // See Note [CNFs in compacting GC] above. + rehash_CNFs(); } ===================================== testsuite/config/ghc ===================================== @@ -29,7 +29,9 @@ config.other_ways = ['prof', 'normal_h', 'ext-interp', 'nonmoving', 'nonmoving_thr', - 'nonmoving_thr_ghc'] + 'nonmoving_thr_ghc', + 'compacting_gc', + ] if ghc_with_native_codegen: config.compile_ways.append('optasm') @@ -105,6 +107,7 @@ config.way_flags = { 'nonmoving' : [], 'nonmoving_thr': ['-threaded'], 'nonmoving_thr_ghc': ['+RTS', '-xn', '-N2', '-RTS', '-threaded'], + 'compacting_gc': [], } config.way_rts_flags = { @@ -146,6 +149,7 @@ config.way_rts_flags = { 'nonmoving' : ['-xn'], 'nonmoving_thr' : ['-xn', '-N2'], 'nonmoving_thr_ghc': ['-xn', '-N2'], + 'compacting_gc': ['-c'], } # Useful classes of ways that can be used with only_ways(), omit_ways() and ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8e100ead0c5d8c7d12ae3079ed6f5f0307ed073...55edd9157402b9ff4cffc00790100f783845d8b4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8e100ead0c5d8c7d12ae3079ed6f5f0307ed073...55edd9157402b9ff4cffc00790100f783845d8b4 You're receiving 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 9 13:34:39 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 09 Apr 2020 09:34:39 -0400 Subject: [Git][ghc/ghc][wip/T17173] Do eager instantation in terms Message-ID: <5e8f246f25172_616776d1c74400672f@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 8531783a by Simon Peyton Jones at 2020-04-09T14:33:55+01:00 Do eager instantation in terms This is a first draft of a patch for #17173. It will need a proper commit message before we are done! - - - - - 14 changed files: - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/quantified-constraints/T17458.stderr - testsuite/tests/typecheck/should_compile/T18005.hs - testsuite/tests/typecheck/should_fail/T3176.stderr Changes: ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -91,7 +91,7 @@ tcProc pat cmd exp_ty ; (co, (exp_ty1, res_ty)) <- matchExpectedAppTy exp_ty ; (co1, (arr_ty, arg_ty)) <- matchExpectedAppTy exp_ty1 ; let cmd_env = CmdEnv { cmd_arr = arr_ty } - ; (pat', cmd') <- tcPat ProcExpr pat (mkCheckExpType arg_ty) $ + ; (pat', cmd') <- tcCheckPat ProcExpr pat arg_ty $ tcCmdTop cmd_env cmd (unitTy, res_ty) ; let res_co = mkTcTransCo co (mkTcAppCo co1 (mkTcNomReflCo res_ty)) @@ -371,7 +371,7 @@ tcArrDoStmt env _ (BodyStmt _ rhs _ _) res_ty thing_inside tcArrDoStmt env ctxt (BindStmt _ pat rhs _ _) res_ty thing_inside = do { (rhs', pat_ty) <- tc_arr_rhs env rhs - ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ + ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside res_ty ; return (mkTcBindStmt pat' rhs', thing) } ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -1366,7 +1366,7 @@ tcLhs sig_fn no_gen (PatBind { pat_lhs = pat, pat_rhs = grhss }) -- See Note [Existentials in pattern bindings] ; ((pat', nosig_mbis), pat_ty) <- addErrCtxt (patMonoBindsCtxt pat grhss) $ - tcInferNoInst $ \ exp_ty -> + tcInferInst $ \ exp_ty -> -- The ir_inst field is irrelevant for patterns tcLetPat inst_sig_fun no_gen pat exp_ty $ mapM lookup_info nosig_names ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -14,14 +14,9 @@ -- | Typecheck an expression module GHC.Tc.Gen.Expr ( tcPolyExpr - , tcMonoExpr - , tcMonoExprNC - , tcInferSigma - , tcInferSigmaNC - , tcInferRho - , tcInferRhoNC - , tcSyntaxOp - , tcSyntaxOpGen + , tcMonoExpr, tcMonoExprNC + , tcInferRho, tcInferRhoNC, tcInferAppHead + , tcSyntaxOp, tcSyntaxOpGen , SyntaxOpType(..) , synKnownType , tcCheckId @@ -151,25 +146,14 @@ tcMonoExprNC (L loc expr) res_ty ; return (L loc expr') } --------------- -tcInferSigma, tcInferSigmaNC :: LHsExpr GhcRn -> TcM ( LHsExpr GhcTcId - , TcSigmaType ) --- Infer a *sigma*-type. -tcInferSigma expr = addErrCtxt (exprCtxt expr) (tcInferSigmaNC expr) - -tcInferSigmaNC (L loc expr) - = setSrcSpan loc $ - do { (expr', sigma) <- tcInferNoInst (tcExpr expr) - ; return (L loc expr', sigma) } - tcInferRho, tcInferRhoNC :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcRhoType) -- Infer a *rho*-type. The return type is always (shallowly) instantiated. tcInferRho expr = addErrCtxt (exprCtxt expr) (tcInferRhoNC expr) -tcInferRhoNC expr - = do { (expr', sigma) <- tcInferSigmaNC expr - ; (wrap, rho) <- topInstantiate (lexprCtOrigin expr) sigma - ; return (mkLHsWrap wrap expr', rho) } - +tcInferRhoNC (L loc expr) + = setSrcSpan loc $ + do { (expr', rho) <- tcInferInst (tcExpr expr) + ; return (L loc expr', rho) } {- ************************************************************************ @@ -281,13 +265,9 @@ tcExpr e@(HsLamCase x matches) res_ty , text "requires"] match_ctxt = MC { mc_what = CaseAlt, mc_body = tcBody } -tcExpr e@(ExprWithTySig _ expr sig_ty) res_ty - = do { let loc = getLoc (hsSigWcType sig_ty) - ; sig_info <- checkNoErrs $ -- Avoid error cascade - tcUserTypeSig loc sig_ty Nothing - ; (expr', poly_ty) <- tcExprSig expr sig_info - ; let expr'' = ExprWithTySig noExtField expr' sig_ty - ; tcWrapResult e expr'' poly_ty res_ty } +tcExpr e@(ExprWithTySig _ expr hs_ty) res_ty + = do { (expr', poly_ty) <- tcExprWithSig expr hs_ty + ; tcWrapResult e expr' poly_ty res_ty } {- Note [Type-checking overloaded labels] @@ -352,7 +332,7 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty | (L loc (HsVar _ (L lv op_name))) <- op , op_name `hasKey` dollarIdKey -- Note [Typing rule for ($)] = do { traceTc "Application rule" (ppr op) - ; (arg1', arg1_ty) <- tcInferSigma arg1 + ; (arg1', arg1_ty) <- tcInferAppHead arg1 ; let doc = text "The first argument of ($) takes" orig1 = lexprCtOrigin arg1 @@ -413,7 +393,7 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty -- \ x -> op x expr tcExpr expr@(SectionR x op arg2) res_ty - = do { (op', op_ty) <- tcInferFun op + = do { (op', op_ty) <- tcInferAppHead op ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty ; wrap_res <- tcSubTypeHR SectionOrigin (Just expr) @@ -428,7 +408,7 @@ tcExpr expr@(SectionR x op arg2) res_ty -- See #13285 tcExpr expr@(SectionL x arg1 op) res_ty - = do { (op', op_ty) <- tcInferFun op + = do { (op', op_ty) <- tcInferAppHead op ; dflags <- getDynFlags -- Note [Left sections] ; let n_reqd_args | xopt LangExt.PostfixOperators dflags = 1 | otherwise = 2 @@ -1009,6 +989,23 @@ tcExpr other _ = pprPanic "tcMonoExpr" (ppr other) -- Include ArrForm, ArrApp, which shouldn't appear at all -- Also HsTcBracketOut, HsQuasiQuoteE + +{- ********************************************************************* +* * + Expression with type signature e::ty +* * +********************************************************************* -} + +tcExprWithSig :: LHsExpr GhcRn -> LHsSigWcType (NoGhcTc GhcRn) + -> TcM (HsExpr GhcTc, TcSigmaType) +tcExprWithSig expr hs_ty + = do { sig_info <- checkNoErrs $ -- Avoid error cascade + tcUserTypeSig loc hs_ty Nothing + ; (expr', poly_ty) <- tcExprSig expr sig_info + ; return (ExprWithTySig noExtField expr' hs_ty, poly_ty) } + where + loc = getLoc (hsSigWcType hs_ty) + {- ************************************************************************ * * @@ -1147,7 +1144,7 @@ tcApp _m_herald (L loc (HsVar _ (L _ fun_id))) args res_ty n_val_args = count isHsValArg args tcApp m_herald fun args res_ty - = do { (tc_fun, fun_ty) <- tcInferFun fun + = do { (tc_fun, fun_ty) <- tcInferAppHead fun ; tcFunApp m_herald fun tc_fun fun_ty args res_ty } --------------------- @@ -1198,23 +1195,27 @@ mk_op_msg :: LHsExpr GhcRn -> SDoc mk_op_msg op = text "The operator" <+> quotes (ppr op) <+> text "takes" ---------------- -tcInferFun :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcSigmaType) --- Infer type of a function -tcInferFun (L loc (HsVar _ (L _ name))) - = do { (fun, ty) <- setSrcSpan loc (tcInferId name) - -- Don't wrap a context around a plain Id - ; return (L loc fun, ty) } - -tcInferFun (L loc (HsRecFld _ f)) - = do { (fun, ty) <- setSrcSpan loc (tcInferRecSelId f) - -- Don't wrap a context around a plain Id - ; return (L loc fun, ty) } - -tcInferFun fun - = tcInferSigma fun - -- NB: tcInferSigma; see GHC.Tc.Utils.Unify - -- Note [Deep instantiation of InferResult] in GHC.Tc.Utils.Unify +tcInferAppHead :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcSigmaType) +-- Infer type of the head of an application, +-- i.e. the 'f' in (f e1 ... en) +-- We get back a SigmaType because we have special cases for +-- * A bare identifier (just look it up) +-- This case also covers a record selectro HsRecFld +-- * An expression with a type signature (e :: ty) + +tcInferAppHead el@(L loc e) + = case e of + HsVar _ (L _ nm) -> add_loc $ tcInferId nm + HsRecFld _ f -> add_loc $ tcInferRecSelId f + ExprWithTySig _ e hs_ty -> add_loc_ctxt $ tcExprWithSig e hs_ty + _ -> add_loc_ctxt $ tcInferInst (tcExpr e) + where + add_loc_ctxt thing = addErrCtxt (exprCtxt el) $ + add_loc thing + add_loc thing = setSrcSpan loc $ + do { (e', ty) <- thing + ; return (L loc e', ty) } ---------------- -- | Type-check the arguments to a function, possibly including visible type @@ -1431,7 +1432,7 @@ tcSyntaxOpGen :: CtOrigin -> ([TcSigmaType] -> TcM a) -> TcM (a, SyntaxExprTc) tcSyntaxOpGen orig (SyntaxExprRn op) arg_tys res_ty thing_inside - = do { (expr, sigma) <- tcInferSigma $ noLoc op + = do { (expr, sigma) <- tcInferAppHead $ noLoc op ; traceTc "tcSyntaxOpGen" (ppr op $$ ppr expr $$ ppr sigma) ; (result, expr_wrap, arg_wraps, res_wrap) <- tcSynArgA orig sigma arg_tys res_ty $ @@ -1711,7 +1712,7 @@ tcCheckId name res_ty ; traceTc "tcCheckId" (vcat [ppr name, ppr actual_res_ty, ppr res_ty]) ; addFunResCtxt False (HsVar noExtField (noLoc name)) actual_res_ty res_ty $ tcWrapResultO (OccurrenceOf name) (HsVar noExtField (noLoc name)) expr - actual_res_ty res_ty } + actual_res_ty res_ty } tcCheckRecSelId :: HsExpr GhcRn -> AmbiguousFieldOcc GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId) tcCheckRecSelId rn_expr f@(Unambiguous _ (L _ lbl)) res_ty ===================================== compiler/GHC/Tc/Gen/Expr.hs-boot ===================================== @@ -6,23 +6,15 @@ import GHC.Tc.Types ( TcM ) import GHC.Tc.Types.Origin ( CtOrigin ) import GHC.Hs.Extension ( GhcRn, GhcTcId ) -tcPolyExpr :: - LHsExpr GhcRn - -> TcSigmaType - -> TcM (LHsExpr GhcTcId) - -tcMonoExpr, tcMonoExprNC :: - LHsExpr GhcRn - -> ExpRhoType - -> TcM (LHsExpr GhcTcId) - -tcInferSigma :: - LHsExpr GhcRn - -> TcM (LHsExpr GhcTcId, TcSigmaType) - -tcInferRho, tcInferRhoNC :: - LHsExpr GhcRn - -> TcM (LHsExpr GhcTcId, TcRhoType) +tcPolyExpr :: LHsExpr GhcRn -> TcSigmaType -> TcM (LHsExpr GhcTcId) + +tcMonoExpr, tcMonoExprNC + :: LHsExpr GhcRn -> ExpRhoType -> TcM (LHsExpr GhcTcId) + +tcInferRho, tcInferRhoNC + :: LHsExpr GhcRn-> TcM (LHsExpr GhcTcId, TcRhoType) + +tcInferAppHead :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcSigmaType) tcSyntaxOp :: CtOrigin -> SyntaxExprRn ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -60,7 +60,7 @@ module GHC.Tc.Gen.HsType ( checkClassKindSig, -- Pattern type signatures - tcHsPatSigType, tcPatSig, + tcHsPatSigType, -- Error messages funAppCtxt, addTyConFlavCtxt @@ -75,7 +75,6 @@ import GHC.Tc.Utils.Monad import GHC.Tc.Types.Origin import GHC.Core.Predicate import GHC.Tc.Types.Constraint -import GHC.Tc.Types.Evidence import GHC.Tc.Utils.Env import GHC.Tc.Utils.TcMType import GHC.Tc.Validity @@ -3345,58 +3344,6 @@ tcHsPatSigType ctxt sig_ty tcHsPatSigType _ (HsWC _ (XHsImplicitBndrs nec)) = noExtCon nec tcHsPatSigType _ (XHsWildCardBndrs nec) = noExtCon nec -tcPatSig :: Bool -- True <=> pattern binding - -> LHsSigWcType GhcRn - -> ExpSigmaType - -> TcM (TcType, -- The type to use for "inside" the signature - [(Name,TcTyVar)], -- The new bit of type environment, binding - -- the scoped type variables - [(Name,TcTyVar)], -- The wildcards - HsWrapper) -- Coercion due to unification with actual ty - -- Of shape: res_ty ~ sig_ty -tcPatSig in_pat_bind sig res_ty - = do { (sig_wcs, sig_tvs, sig_ty) <- tcHsPatSigType PatSigCtxt sig - -- sig_tvs are the type variables free in 'sig', - -- and not already in scope. These are the ones - -- that should be brought into scope - - ; if null sig_tvs then do { - -- Just do the subsumption check and return - wrap <- addErrCtxtM (mk_msg sig_ty) $ - tcSubTypeET PatSigOrigin PatSigCtxt res_ty sig_ty - ; return (sig_ty, [], sig_wcs, wrap) - } else do - -- Type signature binds at least one scoped type variable - - -- A pattern binding cannot bind scoped type variables - -- It is more convenient to make the test here - -- than in the renamer - { when in_pat_bind (addErr (patBindSigErr sig_tvs)) - - -- Now do a subsumption check of the pattern signature against res_ty - ; wrap <- addErrCtxtM (mk_msg sig_ty) $ - tcSubTypeET PatSigOrigin PatSigCtxt res_ty sig_ty - - -- Phew! - ; return (sig_ty, sig_tvs, sig_wcs, wrap) - } } - where - mk_msg sig_ty tidy_env - = do { (tidy_env, sig_ty) <- zonkTidyTcType tidy_env sig_ty - ; res_ty <- readExpType res_ty -- should be filled in by now - ; (tidy_env, res_ty) <- zonkTidyTcType tidy_env res_ty - ; let msg = vcat [ hang (text "When checking that the pattern signature:") - 4 (ppr sig_ty) - , nest 2 (hang (text "fits the type of its context:") - 2 (ppr res_ty)) ] - ; return (tidy_env, msg) } - -patBindSigErr :: [(Name,TcTyVar)] -> SDoc -patBindSigErr sig_tvs - = hang (text "You cannot bind scoped type variable" <> plural sig_tvs - <+> pprQuotedList (map fst sig_tvs)) - 2 (text "in a pattern binding signature") - {- Note [Pattern signature binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also Note [Type variables in the type environment] in GHC.Tc.Utils. ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -422,8 +422,8 @@ tcGuardStmt _ (BodyStmt _ guard _ _) res_ty thing_inside tcGuardStmt ctxt (BindStmt _ pat rhs _ _) res_ty thing_inside = do { (rhs', rhs_ty) <- tcInferRhoNC rhs -- Stmt has a context already - ; (pat', thing) <- tcPat_O (StmtCtxt ctxt) (lexprCtOrigin rhs) - pat (mkCheckExpType rhs_ty) $ + ; (pat', thing) <- tcCheckPat_O (StmtCtxt ctxt) (lexprCtOrigin rhs) + pat rhs_ty $ thing_inside res_ty ; return (mkTcBindStmt pat' rhs', thing) } @@ -456,7 +456,7 @@ tcLcStmt _ _ (LastStmt x body noret _) elt_ty thing_inside tcLcStmt m_tc ctxt (BindStmt _ pat rhs _ _) elt_ty thing_inside = do { pat_ty <- newFlexiTyVarTy liftedTypeKind ; rhs' <- tcMonoExpr rhs (mkCheckExpType $ mkTyConApp m_tc [pat_ty]) - ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ + ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside elt_ty ; return (mkTcBindStmt pat' rhs', thing) } @@ -580,8 +580,7 @@ tcMcStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside [SynRho, SynFun SynAny SynRho] res_ty $ \ [rhs_ty, pat_ty, new_res_ty] -> do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) - ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat - (mkCheckExpType pat_ty) $ + ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside (mkCheckExpType new_res_ty) ; return (rhs', pat', thing, new_res_ty) } @@ -840,8 +839,7 @@ tcDoStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside <- tcSyntaxOp DoOrigin bind_op [SynRho, SynFun SynAny SynRho] res_ty $ \ [rhs_ty, pat_ty, new_res_ty] -> do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) - ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat - (mkCheckExpType pat_ty) $ + ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside (mkCheckExpType new_res_ty) ; return (rhs', pat', new_res_ty, thing) } @@ -1038,7 +1036,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside = setSrcSpan (combineSrcSpans (getLoc pat) (getLoc rhs)) $ addErrCtxt (pprStmtInCtxt ctxt (mkBindStmt pat rhs)) $ do { rhs' <- tcMonoExprNC rhs (mkCheckExpType exp_ty) - ; (pat', _) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ + ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ return () ; fail_op' <- tcMonadFailOp (DoPatOrigin pat) pat' fail_op body_ty @@ -1054,7 +1052,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside tcStmtsAndThen ctxt tcDoStmt stmts (mkCheckExpType exp_ty) $ \res_ty -> do { L _ ret' <- tcMonoExprNC (noLoc ret) res_ty - ; (pat', _) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ + ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ return () ; return (ret', pat') } ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -16,8 +16,7 @@ module GHC.Tc.Gen.Pat ( tcLetPat , newLetBndr , LetBndrSpec(..) - , tcPat - , tcPat_O + , tcCheckPat, tcCheckPat_O, tcInferPat , tcPats , addDataConStupidTheta , badFieldCon @@ -29,7 +28,7 @@ where import GhcPrelude -import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferSigma ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferAppHead ) import GHC.Hs import GHC.Tc.Utils.Zonk @@ -63,6 +62,7 @@ import Util import Outputable import qualified GHC.LanguageExtensions as LangExt import Control.Arrow ( second ) +import Control.Monad ( when ) import ListSetOps ( getNth ) {- @@ -112,20 +112,29 @@ tcPats ctxt pats pat_tys thing_inside where penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = PatOrigin } -tcPat :: HsMatchContext GhcRn - -> LPat GhcRn -> ExpSigmaType - -> TcM a -- Checker for body - -> TcM (LPat GhcTcId, a) -tcPat ctxt = tcPat_O ctxt PatOrigin +tcInferPat :: HsMatchContext GhcRn -> LPat GhcRn + -> TcM a + -> TcM ((LPat GhcTcId, a), TcSigmaType) +tcInferPat ctxt pat thing_inside + = tcInferInst $ \ exp_ty -> -- The ir_inst flag is irrelevant in tcPat + tc_lpat pat exp_ty penv thing_inside + where + penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = PatOrigin } + +tcCheckPat :: HsMatchContext GhcRn + -> LPat GhcRn -> TcSigmaType + -> TcM a -- Checker for body + -> TcM (LPat GhcTcId, a) +tcCheckPat ctxt = tcCheckPat_O ctxt PatOrigin -- | A variant of 'tcPat' that takes a custom origin -tcPat_O :: HsMatchContext GhcRn - -> CtOrigin -- ^ origin to use if the type needs inst'ing - -> LPat GhcRn -> ExpSigmaType - -> TcM a -- Checker for body - -> TcM (LPat GhcTcId, a) -tcPat_O ctxt orig pat pat_ty thing_inside - = tc_lpat pat pat_ty penv thing_inside +tcCheckPat_O :: HsMatchContext GhcRn + -> CtOrigin -- ^ origin to use if the type needs inst'ing + -> LPat GhcRn -> TcSigmaType + -> TcM a -- Checker for body + -> TcM (LPat GhcTcId, a) +tcCheckPat_O ctxt orig pat pat_ty thing_inside + = tc_lpat pat (mkCheckExpType pat_ty) penv thing_inside where penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = orig } @@ -390,22 +399,25 @@ tc_pat penv (AsPat x (L nm_loc name) pat) pat_ty thing_inside tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside = do { - -- Expr must have type `forall a1...aN. OPT' -> B` - -- where overall_pat_ty is an instance of OPT'. - ; (expr',expr'_inferred) <- tcInferSigma expr - - -- expression must be a function + -- Using tcInferAppHead here, rather than tcMonoExpr, lets us + -- have view functions with types like: + -- (forall a. blah) -> forall b. burble + -- So the overall_pat_ty is (forall a. blah), while the + -- inner pattern is checked with (forall b. burble) + ; (expr',expr_ty) <- tcInferAppHead expr + + -- Expression must be a function ; let expr_orig = lexprCtOrigin expr herald = text "A view pattern expression expects" ; (expr_wrap1, [inf_arg_ty], inf_res_ty) - <- matchActualFunTys herald expr_orig (Just (unLoc expr)) 1 expr'_inferred - -- expr_wrap1 :: expr'_inferred "->" (inf_arg_ty -> inf_res_ty) + <- matchActualFunTys herald expr_orig (Just (unLoc expr)) 1 expr_ty + -- expr_wrap1 :: expr_ty "->" (inf_arg_ty -> inf_res_ty) - -- check that overall pattern is more polymorphic than arg type + -- Check that overall pattern is more polymorphic than arg type ; expr_wrap2 <- tcSubTypePat penv overall_pat_ty inf_arg_ty -- expr_wrap2 :: overall_pat_ty "->" inf_arg_ty - -- pattern must have inf_res_ty + -- Pattern must have inf_res_ty ; (pat', res) <- tc_lpat pat (mkCheckExpType inf_res_ty) penv thing_inside ; overall_pat_ty <- readExpType overall_pat_ty @@ -665,6 +677,66 @@ because they won't be in scope when we do the desugaring ************************************************************************ +* * + Pattern signatures (pat :: type) +* * +************************************************************************ +-} + +tcPatSig :: Bool -- True <=> pattern binding + -> LHsSigWcType GhcRn + -> ExpSigmaType + -> TcM (TcType, -- The type to use for "inside" the signature + [(Name,TcTyVar)], -- The new bit of type environment, binding + -- the scoped type variables + [(Name,TcTyVar)], -- The wildcards + HsWrapper) -- Coercion due to unification with actual ty + -- Of shape: res_ty ~ sig_ty +tcPatSig in_pat_bind sig res_ty + = do { (sig_wcs, sig_tvs, sig_ty) <- tcHsPatSigType PatSigCtxt sig + -- sig_tvs are the type variables free in 'sig', + -- and not already in scope. These are the ones + -- that should be brought into scope + + ; if null sig_tvs then do { + -- Just do the subsumption check and return + wrap <- addErrCtxtM (mk_msg sig_ty) $ + tcSubTypeET PatSigOrigin PatSigCtxt res_ty sig_ty + ; return (sig_ty, [], sig_wcs, wrap) + } else do + -- Type signature binds at least one scoped type variable + + -- A pattern binding cannot bind scoped type variables + -- It is more convenient to make the test here + -- than in the renamer + { when in_pat_bind (addErr (patBindSigErr sig_tvs)) + + -- Now do a subsumption check of the pattern signature against res_ty + ; wrap <- addErrCtxtM (mk_msg sig_ty) $ + tcSubTypeET PatSigOrigin PatSigCtxt res_ty sig_ty + + -- Phew! + ; return (sig_ty, sig_tvs, sig_wcs, wrap) + } } + where + mk_msg sig_ty tidy_env + = do { (tidy_env, sig_ty) <- zonkTidyTcType tidy_env sig_ty + ; res_ty <- readExpType res_ty -- should be filled in by now + ; (tidy_env, res_ty) <- zonkTidyTcType tidy_env res_ty + ; let msg = vcat [ hang (text "When checking that the pattern signature:") + 4 (ppr sig_ty) + , nest 2 (hang (text "fits the type of its context:") + 2 (ppr res_ty)) ] + ; return (tidy_env, msg) } + +patBindSigErr :: [(Name,TcTyVar)] -> SDoc +patBindSigErr sig_tvs + = hang (text "You cannot bind scoped type variable" <> plural sig_tvs + <+> pprQuotedList (map fst sig_tvs)) + 2 (text "in a pattern binding signature") + + +{- ********************************************************************* * * Most of the work for constructors is here (the rest is in the ConPatIn case of tc_pat) ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -56,7 +56,6 @@ import GHC.Iface.Env ( externaliseName ) import GHC.Tc.Gen.HsType import GHC.Tc.Validity( checkValidType ) import GHC.Tc.Gen.Match -import GHC.Tc.Utils.Instantiate( deeplyInstantiate ) import GHC.Tc.Utils.Unify( checkConstraints ) import GHC.Rename.HsType import GHC.Rename.Expr @@ -2492,15 +2491,12 @@ tcRnExpr hsc_env mode rdr_expr -- Now typecheck the expression, and generalise its type -- it might have a rank-2 type (e.g. :t runST) uniq <- newUnique ; - let { fresh_it = itName uniq (getLoc rdr_expr) - ; orig = lexprCtOrigin rn_expr } ; + let { fresh_it = itName uniq (getLoc rdr_expr) } ; ((tclvl, res_ty), lie) <- captureTopConstraints $ pushTcLevelM $ - do { (_tc_expr, expr_ty) <- tcInferSigma rn_expr - ; if inst - then snd <$> deeplyInstantiate orig expr_ty - else return expr_ty } ; + do { (_tc_expr, expr_ty) <- tc_infer rn_expr + ; return expr_ty } ; -- Generalise (qtvs, dicts, _, residual, _) @@ -2526,6 +2522,8 @@ tcRnExpr hsc_env mode rdr_expr return (snd (normaliseType fam_envs Nominal ty)) } where + tc_infer | inst = tcInferRhoNC + | otherwise = tcInferAppHead -- See Note [TcRnExprMode] (inst, infer_mode, perhaps_disable_default_warnings) = case mode of TM_Inst -> (True, NoRestrictions, id) ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -149,8 +149,7 @@ tcInferPatSynDecl (PSB { psb_id = lname@(L _ name), psb_args = details ; let (arg_names, rec_fields, is_infix) = collectPatSynArgInfo details ; (tclvl, wanted, ((lpat', args), pat_ty)) <- pushLevelAndCaptureConstraints $ - tcInferNoInst $ \ exp_ty -> - tcPat PatSyn lpat exp_ty $ + tcInferPat PatSyn lpat $ mapM tcLookupId arg_names ; let (ex_tvs, prov_dicts) = tcCollectEx lpat' @@ -389,9 +388,9 @@ tcCheckPatSynDecl psb at PSB{ psb_id = lname@(L _ name), psb_args = details ; req_dicts <- newEvVars req_theta ; (tclvl, wanted, (lpat', (ex_tvs', prov_dicts, args'))) <- ASSERT2( equalLength arg_names arg_tys, ppr name $$ ppr arg_names $$ ppr arg_tys ) - pushLevelAndCaptureConstraints $ - tcExtendTyVarEnv univ_tvs $ - tcPat PatSyn lpat (mkCheckExpType pat_ty) $ + pushLevelAndCaptureConstraints $ + tcExtendTyVarEnv univ_tvs $ + tcCheckPat PatSyn lpat pat_ty $ do { let in_scope = mkInScopeSet (mkVarSet univ_tvs) empty_subst = mkEmptyTCvSubst in_scope ; (subst, ex_tvs') <- mapAccumLM newMetaTyVarX empty_subst ex_tvs ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -835,9 +835,8 @@ addLocM :: (a -> TcM b) -> Located a -> TcM b addLocM fn (L loc a) = setSrcSpan loc $ fn a wrapLocM :: (a -> TcM b) -> Located a -> TcM (Located b) --- wrapLocM :: (a -> TcM b) -> Located a -> TcM (Located b) wrapLocM fn (L loc a) = setSrcSpan loc $ do { b <- fn a - ; return (L loc b) } + ; return (L loc b) } wrapLocFstM :: (a -> TcM (b,c)) -> Located a -> TcM (Located b, c) wrapLocFstM fn (L loc a) = ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -563,13 +563,9 @@ tcSubTypeET orig ctxt (Check ty_actual) ty_expected , uo_visible = True } tcSubTypeET _ _ (Infer inf_res) ty_expected - = ASSERT2( not (ir_inst inf_res), ppr inf_res $$ ppr ty_expected ) - -- An (Infer inf_res) ExpSigmaType passed into tcSubTypeET never - -- has the ir_inst field set. Reason: in patterns (which is what - -- tcSubTypeET is used for) do not aggressively instantiate - do { co <- fill_infer_result ty_expected inf_res - -- Since ir_inst is false, we can skip fillInferResult - -- and go straight to fill_infer_result + = do { co <- fillInferResult ty_expected inf_res + -- In patterns we ignore the ir_inst field + -- and never instantatiate ; return (mkWpCastN (mkTcSymCo co)) } @@ -643,7 +639,7 @@ tcSubTypeDS_NC_O :: CtOrigin -- origin used for instantiation only -- ty_expected is deeply skolemised tcSubTypeDS_NC_O inst_orig ctxt m_thing ty_actual ty_expected = case ty_expected of - Infer inf_res -> fillInferResult inst_orig ty_actual inf_res + Infer inf_res -> instantiateAndFillInferResult inst_orig ty_actual inf_res Check ty -> tc_sub_type_ds eq_orig inst_orig ctxt ty_actual ty where eq_orig = TypeEqOrigin { uo_actual = ty_actual, uo_expected = ty @@ -864,7 +860,7 @@ tcWrapResultO orig rn_expr expr actual_ty res_ty {- ********************************************************************** %* * - ExpType functions: tcInfer, fillInferResult + ExpType functions: tcInfer, instantiateAndFillInferResult %* * %********************************************************************* -} @@ -884,24 +880,24 @@ tcInfer instantiate tc_check ; res_ty <- readExpType res_ty ; return (result, res_ty) } -fillInferResult :: CtOrigin -> TcType -> InferResult -> TcM HsWrapper --- If wrap = fillInferResult t1 t2 +instantiateAndFillInferResult :: CtOrigin -> TcType -> InferResult -> TcM HsWrapper +-- If wrap = instantiateAndFillInferResult t1 t2 -- => wrap :: t1 ~> t2 -- See Note [Deep instantiation of InferResult] -fillInferResult orig ty inf_res@(IR { ir_inst = instantiate_me }) - | instantiate_me +instantiateAndFillInferResult orig ty inf_res@(IR { ir_inst = instantiate_me }) + | instantiate_me -- This is *the* place where ir_inst is consulted = do { (wrap, rho) <- deeplyInstantiate orig ty - ; co <- fill_infer_result rho inf_res + ; co <- fillInferResult rho inf_res ; return (mkWpCastN co <.> wrap) } | otherwise - = do { co <- fill_infer_result ty inf_res + = do { co <- fillInferResult ty inf_res ; return (mkWpCastN co) } -fill_infer_result :: TcType -> InferResult -> TcM TcCoercionN --- If wrap = fill_infer_result t1 t2 +fillInferResult :: TcType -> InferResult -> TcM TcCoercionN +-- If wrap = fillInferResult t1 t2 -- => wrap :: t1 ~> t2 -fill_infer_result orig_ty (IR { ir_uniq = u, ir_lvl = res_lvl +fillInferResult orig_ty (IR { ir_uniq = u, ir_lvl = res_lvl , ir_ref = ref }) = do { (ty_co, ty_to_fill_with) <- promoteTcType res_lvl orig_ty ===================================== testsuite/tests/quantified-constraints/T17458.stderr ===================================== @@ -1,5 +1,5 @@ -T17458.hs:32:27: error: +T17458.hs:32:32: error: • Reduction stack overflow; size = 201 When simplifying the following type: Typeable Void Use -freduction-depth=0 to disable this check ===================================== testsuite/tests/typecheck/should_compile/T18005.hs ===================================== @@ -27,4 +27,5 @@ unT2b' :: T2b -> S2 unT2b' (MkT2b x) = x pattern MkT2b' :: S2 -> T2b -pattern MkT2b' {unT2b} <- (unT2b' -> unT2b) +-- pattern MkT2b' {unT2b} <- (unT2b' -> unT2b) +pattern MkT2b' x <- (unT2b' -> x) ===================================== testsuite/tests/typecheck/should_fail/T3176.stderr ===================================== @@ -1,7 +1,8 @@ -T3176.hs:9:27: - Cannot use record selector ‘unES’ as a function due to escaped type variables - Probable fix: use pattern-matching syntax instead - In the expression: unES - In the second argument of ‘($)’, namely ‘unES $ f t’ - In the expression: show $ unES $ f t +T3176.hs:9:27: error: + • Cannot use record selector ‘unES’ as a function due to escaped type variables + Probable fix: use pattern-matching syntax instead + • In the second argument of ‘($)’, namely ‘unES $ f t’ + In the expression: show $ unES $ f t + In an equation for ‘smallPrintES’: + smallPrintES f t = show $ unES $ f t View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8531783ae7eb9f2f8bc76508e16fd6fc5d00e844 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8531783ae7eb9f2f8bc76508e16fd6fc5d00e844 You're receiving 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 9 15:29:29 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 09 Apr 2020 11:29:29 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18036 Message-ID: <5e8f3f59386f1_61673f81cc90b39c4041948@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18036 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18036 You're receiving 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 9 15:52:24 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 09 Apr 2020 11:52:24 -0400 Subject: [Git][ghc/ghc][wip/T18036] Fix a buglet in redundant-constraint warnings Message-ID: <5e8f44b8d64b5_61677c82e0c4056592@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18036 at Glasgow Haskell Compiler / GHC Commits: 386b5ad2 by Simon Peyton Jones at 2020-04-09T16:51:46+01:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - 5 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/typecheck/should_compile/T18036.hs - + testsuite/tests/typecheck/should_compile/T18036a.hs - + testsuite/tests/typecheck/should_compile/T18036a.stderr - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1719,19 +1719,26 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind | Just hs_sig_ty <- hs_sig_fn sel_name -- There is a signature in the instance -- See Note [Instance method signatures] - = do { let ctxt = FunSigCtxt sel_name True - ; (sig_ty, hs_wrap) + = do { (sig_ty, hs_wrap) <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty ; let local_meth_ty = idType local_meth_id + ctxt = FunSigCtxt sel_name False + -- False <=> do not report redundant constraints when + -- checking instance-sig <= class-meth-sig + -- The instance-sig is the focus here; the class-meth-sig + -- is fixed (#18036) ; hs_wrap <- addErrCtxtM (methSigCtxt sel_name sig_ty local_meth_ty) $ tcSubType_NC ctxt sig_ty local_meth_ty ; return (sig_ty, hs_wrap) } ; inner_meth_name <- newName (nameOccName sel_name) - ; let inner_meth_id = mkLocalId inner_meth_name sig_ty + ; let ctxt = FunSigCtxt sel_name True + -- True <=> check for redundant constraints in the + -- user-specified instance signature + inner_meth_id = mkLocalId inner_meth_name sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt , sig_loc = getLoc (hsSigType hs_sig_ty) } ===================================== testsuite/tests/typecheck/should_compile/T18036.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +instance Fold Identity where + fold :: Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +-- Here we /should/ warn about redundant constraints in the +-- instance signature, since we can remove them +instance Fold Identity where + fold :: Monoid a => Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.stderr ===================================== @@ -0,0 +1,6 @@ + +T18036a.hs:14:13: warning: [-Wredundant-constraints] + • Redundant constraint: Monoid a + • In the type signature for: + fold :: forall a. Monoid a => Identity a -> a + In the instance declaration for ‘Fold Identity’ ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -702,3 +702,5 @@ test('T17792', normal, compile, ['']) test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) +test('T18036', normal, compile, ['']) +test('T18036a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/386b5ad22ad8724204be13e29f1e5181574880fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/386b5ad22ad8724204be13e29f1e5181574880fa You're receiving 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 9 16:13:15 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Thu, 09 Apr 2020 12:13:15 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] 37 commits: Clean up "Eta reduction for data families" Notes Message-ID: <5e8f499b8fc21_61673f8198ee100c4060993@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ec82dc49 by Josh Meredith at 2020-04-09T12:13:11-04:00 Implement extensible interface files - - - - - 9c0dba4e by Josh Meredith at 2020-04-09T12:13:11-04:00 Change expected stdout for hi file Docs tests - - - - - 32c87ef3 by Josh Meredith at 2020-04-09T12:13:11-04:00 Add comment subtitle section for BinData - - - - - 62b90707 by Josh Meredith at 2020-04-09T12:13:11-04:00 Add some discussion about extensible interfaces to extending_ghc.rst - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cb00cf1f4b77bcc0a5376d427e97b7d98ed52090...62b907072321fd8c93d227c20c970dbd330a2dab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cb00cf1f4b77bcc0a5376d427e97b7d98ed52090...62b907072321fd8c93d227c20c970dbd330a2dab You're receiving 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 9 17:05:27 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Thu, 09 Apr 2020 13:05:27 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] Link to the extensible interface files wiki page from extending_ghc.rst Message-ID: <5e8f55d78c92a_61673f81ef22dee44090325@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: e3f6acc4 by Josh Meredith at 2020-04-10T03:05:11+10:00 Link to the extensible interface files wiki page from extending_ghc.rst - - - - - 1 changed file: - docs/users_guide/extending_ghc.rst Changes: ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -759,9 +759,8 @@ GHC's internal ``Binary`` class. The interface to work with these fields is: writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface deleteIfaceField :: FieldName -> ModIface -> ModIface -These fields are currently serialized at the end of the `.hi` file, with their -own sub-header within the file. A pointer to the sub-header exists after the -way descriptor. +To read an interface file from an external tool without linking to GHC, the format +is described at `Extensible Interface Files`_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e3f6acc45263b6963a5eb508c7883d81970fb999 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e3f6acc45263b6963a5eb508c7883d81970fb999 You're receiving 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 9 20:17:29 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 16:17:29 -0400 Subject: [Git][ghc/ghc][master] 2 commits: hadrian: Use --export-dynamic when linking iserv Message-ID: <5e8f82d9dc2e4_61673f81ef22dee44119360@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 2 changed files: - hadrian/src/Settings/Packages.hs - utils/iserv/ghc.mk Changes: ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -122,6 +122,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , cross ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7802fa17a9a1a0f02fbf95170c13d7a9711a681e...fa66f143a61f2285618c611a27c23815ca588299 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7802fa17a9a1a0f02fbf95170c13d7a9711a681e...fa66f143a61f2285618c611a27c23815ca588299 You're receiving 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 9 20:18:11 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 16:18:11 -0400 Subject: [Git][ghc/ghc][master] Fix CNF handling in compacting GC Message-ID: <5e8f8303d6ccd_61673f8199536d9441234aa@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - 9 changed files: - includes/rts/storage/Closures.h - libraries/ghc-compact/tests/all.T - libraries/ghc-compact/tests/compact_gc.hs - rts/Hash.c - rts/Hash.h - rts/StgMiscClosures.cmm - rts/sm/CNF.c - rts/sm/Compact.c - testsuite/config/ghc Changes: ===================================== includes/rts/storage/Closures.h ===================================== @@ -486,4 +486,7 @@ typedef struct StgCompactNFData_ { StgClosure *result; // Used temporarily to store the result of compaction. Doesn't need to be // a GC root. + struct StgCompactNFData_ *link; + // Used by compacting GC for linking CNFs with threaded hash tables. See + // Note [CNFs in compacting GC] in Compact.c for details. } StgCompactNFData; ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -1,4 +1,4 @@ -setTestOpts(extra_ways(['sanity'])) +setTestOpts(extra_ways(['sanity', 'compacting_gc'])) test('compact_simple', normal, compile_and_run, ['']) test('compact_loop', normal, compile_and_run, ['']) ===================================== libraries/ghc-compact/tests/compact_gc.hs ===================================== @@ -6,6 +6,8 @@ main = do let m = Map.fromList [(x,show x) | x <- [1..(10000::Int)]] c <- compactWithSharing m print =<< compactSize c - c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c); print =<< compactSize c; return c) c [1..10] + c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c) + print =<< compactSize c + return c) c [1..10] print (length (show (getCompact c))) print =<< compactSize c ===================================== rts/Hash.c ===================================== @@ -444,17 +444,13 @@ freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) void mapHashTable(HashTable *table, void *data, MapHashFn fn) { - long segment; - long index; - HashList *hl; - /* The last bucket with something in it is table->max + table->split - 1 */ - segment = (table->max + table->split - 1) / HSEGSIZE; - index = (table->max + table->split - 1) % HSEGSIZE; + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; while (segment >= 0) { while (index >= 0) { - for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { fn(data, hl->key, hl->data); } index--; @@ -464,6 +460,25 @@ mapHashTable(HashTable *table, void *data, MapHashFn fn) } } +void +mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn) +{ + /* The last bucket with something in it is table->max + table->split - 1 */ + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; + + while (segment >= 0) { + while (index >= 0) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + fn(data, &hl->key, hl->data); + } + index--; + } + segment--; + index = HSEGSIZE - 1; + } +} + /* ----------------------------------------------------------------------------- * When we initialize a hash table, we set up the first segment as well, * initializing all of the first segment's hash buckets to NULL. ===================================== rts/Hash.h ===================================== @@ -34,8 +34,10 @@ int keyCountHashTable (HashTable *table); int keysHashTable(HashTable *table, StgWord keys[], int szKeys); typedef void (*MapHashFn)(void *data, StgWord key, const void *value); +typedef void (*MapHashFnKeys)(void *data, StgWord *key, const void *value); void mapHashTable(HashTable *table, void *data, MapHashFn fn); +void mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn); /* Hash table access where the keys are C strings (the strings are * assumed to be allocated by the caller, and mustn't be deallocated ===================================== rts/StgMiscClosures.cmm ===================================== @@ -686,11 +686,11 @@ INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE compaction is in progress and the hash table needs to be scanned by the GC. ------------------------------------------------------------------------- */ -INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_CLEAN object (%p) entered!", R1) never returns; } -INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1) never returns; } ===================================== rts/sm/CNF.c ===================================== @@ -381,6 +381,7 @@ compactNew (Capability *cap, StgWord size) self->nursery = block; self->last = block; self->hash = NULL; + self->link = NULL; block->owner = self; ===================================== rts/sm/Compact.c ===================================== @@ -473,6 +473,67 @@ thread_TSO (StgTSO *tso) return (P_)tso + sizeofW(StgTSO); } +/* ---------------------------------------------------------------------------- + Note [CNFs in compacting GC] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CNF hash table keys point outside of the CNF so those need to be threaded + and updated during compaction. After compaction we need to re-visit those + hash tables for re-hashing. The list `nfdata_chain` is used for that + purpose. When we thread keys of a CNF we add the CNF to the list. After + compacting is done we re-visit the CNFs in the list and re-hash their + tables. See also #17937 for more details. + ------------------------------------------------------------------------- */ + +static StgCompactNFData *nfdata_chain = NULL; + +static void +thread_nfdata_hash_key(void *data STG_UNUSED, StgWord *key, const void *value STG_UNUSED) +{ + thread_((void *)key); +} + +static void +add_hash_entry(void *data, StgWord key, const void *value) +{ + HashTable *new_hash = (HashTable *)data; + insertHashTable(new_hash, key, value); +} + +static void +rehash_CNFs(void) +{ + while (nfdata_chain != NULL) { + StgCompactNFData *str = nfdata_chain; + nfdata_chain = str->link; + str->link = NULL; + + HashTable *new_hash = allocHashTable(); + mapHashTable(str->hash, (void*)new_hash, add_hash_entry); + freeHashTable(str->hash, NULL); + str->hash = new_hash; + } +} + +static void +update_fwd_cnf( bdescr *bd ) +{ + while (bd) { + ASSERT(bd->flags & BF_COMPACT); + StgCompactNFData *str = ((StgCompactNFDataBlock*)bd->start)->owner; + + // Thread hash table keys. Values won't be moved as those are inside the + // CNF, and the CNF is a large object and so won't ever move. + if (str->hash) { + mapHashTableKeys(str->hash, NULL, thread_nfdata_hash_key); + ASSERT(str->link == NULL); + str->link = nfdata_chain; + nfdata_chain = str; + } + + bd = bd->link; + } +} static void update_fwd_large( bdescr *bd ) @@ -489,7 +550,6 @@ update_fwd_large( bdescr *bd ) switch (info->type) { case ARR_WORDS: - case COMPACT_NFDATA: // nothing to follow continue; @@ -968,6 +1028,7 @@ compact(StgClosure *static_objects, update_fwd(gc_threads[n]->gens[g].part_list); } update_fwd_large(gen->scavenged_large_objects); + update_fwd_cnf(gen->live_compact_objects); if (g == RtsFlags.GcFlags.generations-1 && gen->old_blocks != NULL) { debugTrace(DEBUG_gc, "update_fwd: %d (compact)", g); update_fwd_compact(gen->old_blocks); @@ -983,4 +1044,8 @@ compact(StgClosure *static_objects, gen->no, gen->n_old_blocks, blocks); gen->n_old_blocks = blocks; } + + // 4. Re-hash hash tables of threaded CNFs. + // See Note [CNFs in compacting GC] above. + rehash_CNFs(); } ===================================== testsuite/config/ghc ===================================== @@ -29,7 +29,9 @@ config.other_ways = ['prof', 'normal_h', 'ext-interp', 'nonmoving', 'nonmoving_thr', - 'nonmoving_thr_ghc'] + 'nonmoving_thr_ghc', + 'compacting_gc', + ] if ghc_with_native_codegen: config.compile_ways.append('optasm') @@ -105,6 +107,7 @@ config.way_flags = { 'nonmoving' : [], 'nonmoving_thr': ['-threaded'], 'nonmoving_thr_ghc': ['+RTS', '-xn', '-N2', '-RTS', '-threaded'], + 'compacting_gc': [], } config.way_rts_flags = { @@ -146,6 +149,7 @@ config.way_rts_flags = { 'nonmoving' : ['-xn'], 'nonmoving_thr' : ['-xn', '-N2'], 'nonmoving_thr_ghc': ['-xn', '-N2'], + 'compacting_gc': ['-c'], } # Useful classes of ways that can be used with only_ways(), omit_ways() and View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/390751768104cd3d2cb57e2037062916476ebd10 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/390751768104cd3d2cb57e2037062916476ebd10 You're receiving 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 9 20:18:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 16:18:54 -0400 Subject: [Git][ghc/ghc][master] Rts: show errno on failure (#18033) Message-ID: <5e8f832e12ee4_616776d1c7441266b1@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 1 changed file: - rts/posix/itimer/Pthread.c Changes: ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -110,13 +110,13 @@ static void *itimer_thread_func(void *_handle_tick) timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { - barf("timerfd_create"); + barf("timerfd_create: %s", strerror(errno)); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { - barf("timerfd_settime"); + barf("timerfd_settime: %s", strerror(errno)); } #endif @@ -124,7 +124,7 @@ static void *itimer_thread_func(void *_handle_tick) if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); + barf("Itimer: read(timerfd) failed: %s", strerror(errno)); } } } else { @@ -170,7 +170,7 @@ initTicker (Time interval, TickProc handle_tick) pthread_setname_np(thread, "ghc_ticker"); #endif } else { - barf("Itimer: Failed to spawn thread"); + barf("Itimer: Failed to spawn thread: %s", strerror(errno)); } } @@ -204,7 +204,7 @@ exitTicker (bool wait) // wait for ticker to terminate if necessary if (wait) { if (pthread_join(thread, NULL)) { - sysErrorBelch("Itimer: Failed to join"); + sysErrorBelch("Itimer: Failed to join: %s", strerror(errno)); } closeMutex(&mutex); closeCondition(&start_cond); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dce50062e35d3246b63fba9357dea6313c23c780 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dce50062e35d3246b63fba9357dea6313c23c780 You're receiving 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 9 20:50:40 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 16:50:40 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: hadrian: Use --export-dynamic when linking iserv Message-ID: <5e8f8aa09319c_61673f8199536d9441314cd@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - e7f76d4d by Hécate at 2020-04-09T16:50:25-04:00 Add an example to liftIO and explain its purpose - - - - - 37f0c5d0 by Sebastian Graf at 2020-04-09T16:50:26-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - c5f002d7 by Sebastian Graf at 2020-04-09T16:50:26-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 2a829409 by Sylvain Henry at 2020-04-09T16:50:28-04:00 Hadrian: fix --summary - - - - - 22 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/TysWiredIn.hs - hadrian/src/Settings/Builders/RunTest.hs - hadrian/src/Settings/Packages.hs - includes/rts/storage/Closures.h - libraries/base/Control/Monad/IO/Class.hs - libraries/ghc-compact/tests/all.T - libraries/ghc-compact/tests/compact_gc.hs - rts/Hash.c - rts/Hash.h - rts/StgMiscClosures.cmm - rts/posix/itimer/Pthread.c - rts/sm/CNF.c - rts/sm/Compact.c - testsuite/config/ghc - utils/iserv/ghc.mk Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -614,7 +614,7 @@ data DataConRep -- and *including* all evidence args , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make + -- 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 @@ -715,8 +715,26 @@ filterEqSpec eq_spec instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- 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,Int) +Why? Because the *wrapper* $WMkT is strict (and its unfolding has case +expressions that do the evals) but the *worker* MkT itself is not. If we +pretend it is strict then when we see + case x of y -> MkT y +the simplifier thinks that y is "sure to be evaluated" (because the worker MkT +is strict) and drops the case. No, the workerId MkT is not strict. + +However, the worker does have StrictnessMarks. When the simplifier sees a +pattern + case e of MkT x -> ... +it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's +fine... dataConRepStrictness comes from the data con not from the worker Id. + +Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment dmdTransform env var dmd | isDataConWorkId var -- Data constructor - = dmdTransformDataConSig (idArity var) (idStrictness var) dmd + = dmdTransformDataConSig (idArity var) dmd | gopt Opt_DmdTxDictSel (ae_dflags env), Just _ <- isClassOpId_maybe var -- Dictionary component selector ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -2758,7 +2758,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.Types.Id.Make +See Note [Data-con worker strictness] in GHC.Core.DataCon NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -45,7 +45,7 @@ module GHC.Core.TyCon( noTcTyConScopedTyVars, -- ** Predicates on TyCons - isAlgTyCon, isVanillaAlgTyCon, + isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon, isClassTyCon, isFamInstTyCon, isFunTyCon, isPrimTyCon, @@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False +-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind. +isConstraintKindCon :: TyCon -> Bool +-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is +-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector +-- for 'tyConUnique' would generate unreachable code for every other data +-- constructor of TyCon (see #18026). +isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey +isConstraintKindCon _ = False + isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except during type inference. -} -isConstraintKindCon :: TyCon -> Bool -isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey - -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). -- E.g. True of TYPE k, TYPE (F Int) ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd = postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty -- see Note [Demands from unsaturated function calls] -dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType +dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType -- Same as dmdTransformSig but for a data constructor (worker), -- which has a special kind of demand transformer. -- If the constructor is saturated, we feed the demand on -- the result into the constructor arguments. -dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res)) - (JD { sd = str, ud = abs }) +dmdTransformDataConSig arity (JD { sd = str, ud = abs }) | Just str_dmds <- go_str arity str , Just abs_dmds <- go_abs arity abs - = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res - -- Must remember whether it's a product, hence con_res, not TopRes + = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv | otherwise -- Not saturated = nopDmdType ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con tycon = dataConTyCon data_con -- The representation TyCon wkr_ty = dataConRepType data_con - ----------- Workers for data types -------------- + ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo `setArityInfo` wkr_arity - `setStrictnessInfo` wkr_sig `setCprInfo` mkCprSig wkr_arity (dataConCPR data_con) `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 @@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con -- setNeverLevPoly wkr_arity = dataConRepArity data_con - wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv - -- 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,Int) - -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has - -- case expressions that do the evals) but the *worker* MkT itself is - -- not. If we pretend it is strict then when we see - -- case x of y -> MkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- the worker MkT is strict) and drops the case. No, the workerId - -- MkT is not strict. - -- - -- However, the worker does have StrictnessMarks. When the simplifier - -- sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - ----------- Workers for newtypes -------------- + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo ===================================== compiler/prelude/TysWiredIn.hs ===================================== @@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon typeSymbolKind = mkTyConTy typeSymbolKindCon constraintKindTyCon :: TyCon +-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon! constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -165,7 +165,7 @@ getTestArgs = do brokenTestArgs = concat [ ["--broken-test", t] | t <- brokenTests args ] speedArg = ["-e", "config.speed=" ++ setTestSpeed (testSpeed args)] summaryArg = case testSummary args of - Just filepath -> Just $ "--summary-file " ++ show filepath + Just filepath -> Just $ "--summary-file=" ++ filepath Nothing -> Just $ "--summary-file=testsuite_summary.txt" junitArg = case testJUnit args of Just filepath -> Just $ "--junit=" ++ filepath ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -122,6 +122,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , cross ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== includes/rts/storage/Closures.h ===================================== @@ -486,4 +486,7 @@ typedef struct StgCompactNFData_ { StgClosure *result; // Used temporarily to store the result of compaction. Doesn't need to be // a GC root. + struct StgCompactNFData_ *link; + // Used by compacting GC for linking CNFs with threaded hash tables. See + // Note [CNFs in compacting GC] in Compact.c for details. } StgCompactNFData; ===================================== libraries/base/Control/Monad/IO/Class.hs ===================================== @@ -30,8 +30,42 @@ module Control.Monad.IO.Class ( class (Monad m) => MonadIO m where -- | Lift a computation from the 'IO' monad. + -- This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations + -- (i.e. 'IO' is the base monad for the stack). + -- + -- === __Example__ + -- + -- + -- > import Control.Monad.Trans.State -- from the "transformers" library + -- > + -- > printState :: Show s => StateT s IO () + -- > printState = do + -- > state <- get + -- > liftIO $ print state + -- + -- + -- Had we omitted @'liftIO'@, we would have ended up with this error: + -- + -- > • Couldn't match type ‘IO’ with ‘StateT s IO’ + -- > Expected type: StateT s IO () + -- > Actual type: IO () + -- + -- The important part here is the mismatch between @StateT s IO ()@ and @'IO' ()@. + -- + -- Luckily, we know of a function that takes an @'IO' a@ and returns an @(m a)@: @'liftIO'@, + -- enabling us to run the program and see the expected results: + -- + -- @ + -- > evalStateT printState "hello" + -- "hello" + -- + -- > evalStateT printState 3 + -- 3 + -- @ + -- liftIO :: IO a -> m a -- | @since 4.9.0.0 instance MonadIO IO where liftIO = id + ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -1,4 +1,4 @@ -setTestOpts(extra_ways(['sanity'])) +setTestOpts(extra_ways(['sanity', 'compacting_gc'])) test('compact_simple', normal, compile_and_run, ['']) test('compact_loop', normal, compile_and_run, ['']) ===================================== libraries/ghc-compact/tests/compact_gc.hs ===================================== @@ -6,6 +6,8 @@ main = do let m = Map.fromList [(x,show x) | x <- [1..(10000::Int)]] c <- compactWithSharing m print =<< compactSize c - c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c); print =<< compactSize c; return c) c [1..10] + c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c) + print =<< compactSize c + return c) c [1..10] print (length (show (getCompact c))) print =<< compactSize c ===================================== rts/Hash.c ===================================== @@ -444,17 +444,13 @@ freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) void mapHashTable(HashTable *table, void *data, MapHashFn fn) { - long segment; - long index; - HashList *hl; - /* The last bucket with something in it is table->max + table->split - 1 */ - segment = (table->max + table->split - 1) / HSEGSIZE; - index = (table->max + table->split - 1) % HSEGSIZE; + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; while (segment >= 0) { while (index >= 0) { - for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { fn(data, hl->key, hl->data); } index--; @@ -464,6 +460,25 @@ mapHashTable(HashTable *table, void *data, MapHashFn fn) } } +void +mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn) +{ + /* The last bucket with something in it is table->max + table->split - 1 */ + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; + + while (segment >= 0) { + while (index >= 0) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + fn(data, &hl->key, hl->data); + } + index--; + } + segment--; + index = HSEGSIZE - 1; + } +} + /* ----------------------------------------------------------------------------- * When we initialize a hash table, we set up the first segment as well, * initializing all of the first segment's hash buckets to NULL. ===================================== rts/Hash.h ===================================== @@ -34,8 +34,10 @@ int keyCountHashTable (HashTable *table); int keysHashTable(HashTable *table, StgWord keys[], int szKeys); typedef void (*MapHashFn)(void *data, StgWord key, const void *value); +typedef void (*MapHashFnKeys)(void *data, StgWord *key, const void *value); void mapHashTable(HashTable *table, void *data, MapHashFn fn); +void mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn); /* Hash table access where the keys are C strings (the strings are * assumed to be allocated by the caller, and mustn't be deallocated ===================================== rts/StgMiscClosures.cmm ===================================== @@ -686,11 +686,11 @@ INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE compaction is in progress and the hash table needs to be scanned by the GC. ------------------------------------------------------------------------- */ -INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_CLEAN object (%p) entered!", R1) never returns; } -INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1) never returns; } ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -110,13 +110,13 @@ static void *itimer_thread_func(void *_handle_tick) timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { - barf("timerfd_create"); + barf("timerfd_create: %s", strerror(errno)); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { - barf("timerfd_settime"); + barf("timerfd_settime: %s", strerror(errno)); } #endif @@ -124,7 +124,7 @@ static void *itimer_thread_func(void *_handle_tick) if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); + barf("Itimer: read(timerfd) failed: %s", strerror(errno)); } } } else { @@ -170,7 +170,7 @@ initTicker (Time interval, TickProc handle_tick) pthread_setname_np(thread, "ghc_ticker"); #endif } else { - barf("Itimer: Failed to spawn thread"); + barf("Itimer: Failed to spawn thread: %s", strerror(errno)); } } @@ -204,7 +204,7 @@ exitTicker (bool wait) // wait for ticker to terminate if necessary if (wait) { if (pthread_join(thread, NULL)) { - sysErrorBelch("Itimer: Failed to join"); + sysErrorBelch("Itimer: Failed to join: %s", strerror(errno)); } closeMutex(&mutex); closeCondition(&start_cond); ===================================== rts/sm/CNF.c ===================================== @@ -381,6 +381,7 @@ compactNew (Capability *cap, StgWord size) self->nursery = block; self->last = block; self->hash = NULL; + self->link = NULL; block->owner = self; ===================================== rts/sm/Compact.c ===================================== @@ -473,6 +473,67 @@ thread_TSO (StgTSO *tso) return (P_)tso + sizeofW(StgTSO); } +/* ---------------------------------------------------------------------------- + Note [CNFs in compacting GC] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CNF hash table keys point outside of the CNF so those need to be threaded + and updated during compaction. After compaction we need to re-visit those + hash tables for re-hashing. The list `nfdata_chain` is used for that + purpose. When we thread keys of a CNF we add the CNF to the list. After + compacting is done we re-visit the CNFs in the list and re-hash their + tables. See also #17937 for more details. + ------------------------------------------------------------------------- */ + +static StgCompactNFData *nfdata_chain = NULL; + +static void +thread_nfdata_hash_key(void *data STG_UNUSED, StgWord *key, const void *value STG_UNUSED) +{ + thread_((void *)key); +} + +static void +add_hash_entry(void *data, StgWord key, const void *value) +{ + HashTable *new_hash = (HashTable *)data; + insertHashTable(new_hash, key, value); +} + +static void +rehash_CNFs(void) +{ + while (nfdata_chain != NULL) { + StgCompactNFData *str = nfdata_chain; + nfdata_chain = str->link; + str->link = NULL; + + HashTable *new_hash = allocHashTable(); + mapHashTable(str->hash, (void*)new_hash, add_hash_entry); + freeHashTable(str->hash, NULL); + str->hash = new_hash; + } +} + +static void +update_fwd_cnf( bdescr *bd ) +{ + while (bd) { + ASSERT(bd->flags & BF_COMPACT); + StgCompactNFData *str = ((StgCompactNFDataBlock*)bd->start)->owner; + + // Thread hash table keys. Values won't be moved as those are inside the + // CNF, and the CNF is a large object and so won't ever move. + if (str->hash) { + mapHashTableKeys(str->hash, NULL, thread_nfdata_hash_key); + ASSERT(str->link == NULL); + str->link = nfdata_chain; + nfdata_chain = str; + } + + bd = bd->link; + } +} static void update_fwd_large( bdescr *bd ) @@ -489,7 +550,6 @@ update_fwd_large( bdescr *bd ) switch (info->type) { case ARR_WORDS: - case COMPACT_NFDATA: // nothing to follow continue; @@ -968,6 +1028,7 @@ compact(StgClosure *static_objects, update_fwd(gc_threads[n]->gens[g].part_list); } update_fwd_large(gen->scavenged_large_objects); + update_fwd_cnf(gen->live_compact_objects); if (g == RtsFlags.GcFlags.generations-1 && gen->old_blocks != NULL) { debugTrace(DEBUG_gc, "update_fwd: %d (compact)", g); update_fwd_compact(gen->old_blocks); @@ -983,4 +1044,8 @@ compact(StgClosure *static_objects, gen->no, gen->n_old_blocks, blocks); gen->n_old_blocks = blocks; } + + // 4. Re-hash hash tables of threaded CNFs. + // See Note [CNFs in compacting GC] above. + rehash_CNFs(); } ===================================== testsuite/config/ghc ===================================== @@ -29,7 +29,9 @@ config.other_ways = ['prof', 'normal_h', 'ext-interp', 'nonmoving', 'nonmoving_thr', - 'nonmoving_thr_ghc'] + 'nonmoving_thr_ghc', + 'compacting_gc', + ] if ghc_with_native_codegen: config.compile_ways.append('optasm') @@ -105,6 +107,7 @@ config.way_flags = { 'nonmoving' : [], 'nonmoving_thr': ['-threaded'], 'nonmoving_thr_ghc': ['+RTS', '-xn', '-N2', '-RTS', '-threaded'], + 'compacting_gc': [], } config.way_rts_flags = { @@ -146,6 +149,7 @@ config.way_rts_flags = { 'nonmoving' : ['-xn'], 'nonmoving_thr' : ['-xn', '-N2'], 'nonmoving_thr_ghc': ['-xn', '-N2'], + 'compacting_gc': ['-c'], } # Useful classes of ways that can be used with only_ways(), omit_ways() and ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55edd9157402b9ff4cffc00790100f783845d8b4...2a829409461c65ca783bb93c7fc1b5978ba33ecf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55edd9157402b9ff4cffc00790100f783845d8b4...2a829409461c65ca783bb93c7fc1b5978ba33ecf You're receiving 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 9 21:49:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 09 Apr 2020 17:49:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/chunked-unpackCString Message-ID: <5e8f987ad9359_61677c82e0c4149082@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/chunked-unpackCString at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/chunked-unpackCString You're receiving 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 9 21:50:10 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 09 Apr 2020 17:50:10 -0400 Subject: [Git][ghc/ghc][wip/chunked-unpackCString] ghc-prim: Strictly in chunks of 32 characters Message-ID: <5e8f98924d33a_6167134ebbc4414922c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/chunked-unpackCString at Glasgow Haskell Compiler / GHC Commits: 3835c945 by Ben Gamari at 2020-04-09T21:50:00+00:00 ghc-prim: Strictly in chunks of 32 characters - - - - - 1 changed file: - libraries/ghc-prim/GHC/CString.hs Changes: ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -93,23 +93,41 @@ the string and the current offset, saving a word for each character unpacked. unpackCString# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCString# #-} -unpackCString# addr - | isTrue# (ch `eqChar#` '\0'#) = [] - | True = C# ch : unpackCString# (addr `plusAddr#` 1#) - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# - + -- See the NOINLINE note on unpackCString# +unpackCString# addr = unpackAppendCString'# [] addr unpackAppendCString# :: Addr# -> [Char] -> [Char] {-# NOINLINE unpackAppendCString# #-} -- See the NOINLINE note on unpackCString# -unpackAppendCString# addr rest - | isTrue# (ch `eqChar#` '\0'#) = rest - | True = C# ch : unpackAppendCString# (addr `plusAddr#` 1#) rest - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# +unpackAppendCString# addr rest = unpackAppendCString'# rest addr + +-- | This is an local helper to reduce duplication between +-- 'unpackCString#' and 'unpackAppendCString#'. Because it is inlined the +-- this gets specialised to @rest = []@ in the former case. +unpackAppendCString'# :: [Char] -> Addr# -> [Char] +{-# INLINE unpackAppendCString'# #-} +unpackAppendCString'# rest addr = unpackChunk addr + where + -- Laziness is expensive: it involves allocating a thunk, then an indirect + -- jump, perhaps some cache misses, etc. However, in practice we find that + -- most applications tend to use at least *some* of their unpacked string. + -- Consequently we unpack eagerly in chunks of this many characters. + -- Compared to fully-lazy unpacking this improves runtime of GHC by about + -- 0.5%. + unpackChunkLen = 32# + + unpackChunk :: Addr# -> [Char] + unpackChunk addr = goStrict addr unpackChunkLen + + goStrict :: Addr# -> Int# -> [Char] + goStrict addr n + | isTrue# (ch `eqChar#` '\0'#) = rest + | isTrue# (n ==# 0#) = unpackChunk addr + | True = let !rest = goStrict (addr `plusAddr#` 1#) (n -# 1#) + in C# ch : rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3835c94569e3da7cc1d46109ff00916f4218aa2c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3835c94569e3da7cc1d46109ff00916f4218aa2c You're receiving 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 9 22:01:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 09 Apr 2020 18:01:46 -0400 Subject: [Git][ghc/ghc][wip/chunked-unpackCString] ghc-prim: Strictly in chunks of 32 characters Message-ID: <5e8f9b4aa0e0_616765c7a284156310@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/chunked-unpackCString at Glasgow Haskell Compiler / GHC Commits: e775ea23 by Ben Gamari at 2020-04-09T22:01:36+00:00 ghc-prim: Strictly in chunks of 32 characters - - - - - 1 changed file: - libraries/ghc-prim/GHC/CString.hs Changes: ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -93,23 +93,45 @@ the string and the current offset, saving a word for each character unpacked. unpackCString# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCString# #-} -unpackCString# addr - | isTrue# (ch `eqChar#` '\0'#) = [] - | True = C# ch : unpackCString# (addr `plusAddr#` 1#) - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# - + -- See the NOINLINE note on unpackCString# +unpackCString# addr = unpackAppendCString'# [] addr unpackAppendCString# :: Addr# -> [Char] -> [Char] {-# NOINLINE unpackAppendCString# #-} -- See the NOINLINE note on unpackCString# -unpackAppendCString# addr rest - | isTrue# (ch `eqChar#` '\0'#) = rest - | True = C# ch : unpackAppendCString# (addr `plusAddr#` 1#) rest - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# +unpackAppendCString# addr rest = unpackAppendCString'# rest addr + +-- | This is an local helper to reduce duplication between +-- 'unpackCString#' and 'unpackAppendCString#'. Because it is inlined the +-- this gets specialised to @rest = []@ in the former case. +unpackAppendCString'# :: [Char] -> Addr# -> [Char] +{-# INLINE unpackAppendCString'# #-} +unpackAppendCString'# rest addr = unpackChunk addr + where + -- Laziness is expensive: it involves allocating a thunk, then an indirect + -- jump, perhaps some cache misses, etc. However, in practice we find that + -- most applications tend to use at least *some* of their unpacked string. + -- Consequently we unpack eagerly in chunks of this many characters. + -- Compared to fully-lazy unpacking this improves runtime of GHC by about + -- 0.5%. + unpackChunkLen = 32# + + unpackChunk :: Addr# -> [Char] + unpackChunk addr = goStrict addr unpackChunkLen + + goStrict :: Addr# -> Int# -> [Char] + goStrict addr n + | isTrue# (ch `eqChar#` '\0'#) = rest + | isTrue# (n ==# 0#) = + -- We've reached the end of our chunk, lazily unpack the next chunk + let rest = unpackChunk (addr `plusAddr#` 1#) + in C# ch : rest + | True = + let !rest = goStrict (addr `plusAddr#` 1#) (n -# 1#) + in C# ch : rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e775ea238332e5a7a0f85b5f346dd7d022430113 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e775ea238332e5a7a0f85b5f346dd7d022430113 You're receiving 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 10 02:07:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 09 Apr 2020 22:07:36 -0400 Subject: [Git][ghc/ghc][wip/chunked-unpackCString] ghc-prim: Strictly in chunks of 32 characters Message-ID: <5e8fd4e82d094_616713503ee041864a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/chunked-unpackCString at Glasgow Haskell Compiler / GHC Commits: 0b02c227 by Ben Gamari at 2020-04-10T02:07:27+00:00 ghc-prim: Strictly in chunks of 32 characters - - - - - 1 changed file: - libraries/ghc-prim/GHC/CString.hs Changes: ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -93,23 +93,45 @@ the string and the current offset, saving a word for each character unpacked. unpackCString# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCString# #-} -unpackCString# addr - | isTrue# (ch `eqChar#` '\0'#) = [] - | True = C# ch : unpackCString# (addr `plusAddr#` 1#) - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# - + -- See the NOINLINE note on unpackCString# +unpackCString# addr = unpackAppendCString'# [] addr unpackAppendCString# :: Addr# -> [Char] -> [Char] {-# NOINLINE unpackAppendCString# #-} -- See the NOINLINE note on unpackCString# -unpackAppendCString# addr rest - | isTrue# (ch `eqChar#` '\0'#) = rest - | True = C# ch : unpackAppendCString# (addr `plusAddr#` 1#) rest - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# +unpackAppendCString# addr rest = unpackAppendCString'# rest addr + +-- | This is an local helper to reduce duplication between +-- 'unpackCString#' and 'unpackAppendCString#'. Because it is inlined the +-- this gets specialised to @rest = []@ in the former case. +unpackAppendCString'# :: [Char] -> Addr# -> [Char] +{-# INLINE unpackAppendCString'# #-} +unpackAppendCString'# rest0 addr0 = unpackChunk addr0 + where + -- Laziness is expensive: it involves allocating a thunk, then an indirect + -- jump, perhaps some cache misses, etc. However, in practice we find that + -- most applications tend to use at least *some* of their unpacked string. + -- Consequently we unpack eagerly in chunks of this many characters. + -- Compared to fully-lazy unpacking this improves runtime of GHC by about + -- 0.5%. + unpackChunkLen = 32# + + unpackChunk :: Addr# -> [Char] + unpackChunk addr = goStrict addr unpackChunkLen + + goStrict :: Addr# -> Int# -> [Char] + goStrict addr n + | isTrue# (ch `eqChar#` '\0'#) = rest0 + | isTrue# (n ==# 0#) = + -- We've reached the end of our chunk, lazily unpack the next chunk + let rest = unpackChunk (addr `plusAddr#` 1#) + in C# ch : rest + | True = + let !rest = goStrict (addr `plusAddr#` 1#) (n -# 1#) + in C# ch : rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b02c227a83b3a0711a5d4e51b515a768f712c46 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b02c227a83b3a0711a5d4e51b515a768f712c46 You're receiving 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 10 02:39:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 09 Apr 2020 22:39:17 -0400 Subject: [Git][ghc/ghc][wip/chunked-unpackCString] ghc-prim: Strictly in chunks of 32 characters Message-ID: <5e8fdc55f399d_6167e4e49b441973dc@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/chunked-unpackCString at Glasgow Haskell Compiler / GHC Commits: ddfdc5fa by Ben Gamari at 2020-04-10T02:39:12+00:00 ghc-prim: Strictly in chunks of 32 characters - - - - - 1 changed file: - libraries/ghc-prim/GHC/CString.hs Changes: ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -93,23 +93,45 @@ the string and the current offset, saving a word for each character unpacked. unpackCString# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCString# #-} -unpackCString# addr - | isTrue# (ch `eqChar#` '\0'#) = [] - | True = C# ch : unpackCString# (addr `plusAddr#` 1#) - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# - + -- See the NOINLINE note on unpackCString# +unpackCString# addr = unpackAppendCString'# [] addr unpackAppendCString# :: Addr# -> [Char] -> [Char] {-# NOINLINE unpackAppendCString# #-} -- See the NOINLINE note on unpackCString# -unpackAppendCString# addr rest - | isTrue# (ch `eqChar#` '\0'#) = rest - | True = C# ch : unpackAppendCString# (addr `plusAddr#` 1#) rest - where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# +unpackAppendCString# addr rest = unpackAppendCString'# rest addr + +-- | This is an local helper to reduce duplication between +-- 'unpackCString#' and 'unpackAppendCString#'. Because it is inlined the +-- this gets specialised to @rest = []@ in the former case. +unpackAppendCString'# :: [Char] -> Addr# -> [Char] +{-# INLINE unpackAppendCString'# #-} +unpackAppendCString'# rest0 addr0 = goStrict addr0 unpackChunkLen + where + -- Laziness is expensive: it involves allocating a thunk, then an indirect + -- jump, perhaps some cache misses, etc. However, in practice we find that + -- most applications tend to use at least *some* of their unpacked string. + -- Consequently we unpack eagerly in chunks of this many characters. + -- Compared to fully-lazy unpacking this improves runtime of GHC by about + -- 0.5%. + unpackChunkLen = 32# + + unpackChunk :: Addr# -> [Char] + unpackChunk addr = goStrict addr unpackChunkLen + + goStrict :: Addr# -> Int# -> [Char] + goStrict addr n + | isTrue# (ch `eqChar#` '\0'#) = rest0 + | isTrue# (n ==# 0#) = + -- We've reached the end of our chunk, lazily unpack the next chunk + let rest = unpackChunk (addr `plusAddr#` 1#) + in C# ch : rest + | True = + let !rest = goStrict (addr `plusAddr#` 1#) (n -# 1#) + in C# ch : rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ddfdc5fa51562c5cc30aa8a89d9f29c613de871e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ddfdc5fa51562c5cc30aa8a89d9f29c613de871e You're receiving 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 10 03:10:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 23:10:52 -0400 Subject: [Git][ghc/ghc][master] Add an example to liftIO and explain its purpose Message-ID: <5e8fe3bcca5b5_616776d1c7442035ba@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 1 changed file: - libraries/base/Control/Monad/IO/Class.hs Changes: ===================================== libraries/base/Control/Monad/IO/Class.hs ===================================== @@ -30,8 +30,42 @@ module Control.Monad.IO.Class ( class (Monad m) => MonadIO m where -- | Lift a computation from the 'IO' monad. + -- This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations + -- (i.e. 'IO' is the base monad for the stack). + -- + -- === __Example__ + -- + -- + -- > import Control.Monad.Trans.State -- from the "transformers" library + -- > + -- > printState :: Show s => StateT s IO () + -- > printState = do + -- > state <- get + -- > liftIO $ print state + -- + -- + -- Had we omitted @'liftIO'@, we would have ended up with this error: + -- + -- > • Couldn't match type ‘IO’ with ‘StateT s IO’ + -- > Expected type: StateT s IO () + -- > Actual type: IO () + -- + -- The important part here is the mismatch between @StateT s IO ()@ and @'IO' ()@. + -- + -- Luckily, we know of a function that takes an @'IO' a@ and returns an @(m a)@: @'liftIO'@, + -- enabling us to run the program and see the expected results: + -- + -- @ + -- > evalStateT printState "hello" + -- "hello" + -- + -- > evalStateT printState 3 + -- 3 + -- @ + -- liftIO :: IO a -> m a -- | @since 4.9.0.0 instance MonadIO IO where liftIO = id + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/045139f40089f288866c1c59c7379be82ecdaf34 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/045139f40089f288866c1c59c7379be82ecdaf34 You're receiving 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 10 03:11:31 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 23:11:31 -0400 Subject: [Git][ghc/ghc][master] Special case `isConstraintKindCon` on `AlgTyCon` Message-ID: <5e8fe3e35fbac_6167136dfb9c420765d@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - 3 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/prelude/TysWiredIn.hs Changes: ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -45,7 +45,7 @@ module GHC.Core.TyCon( noTcTyConScopedTyVars, -- ** Predicates on TyCons - isAlgTyCon, isVanillaAlgTyCon, + isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon, isClassTyCon, isFamInstTyCon, isFunTyCon, isPrimTyCon, @@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False +-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind. +isConstraintKindCon :: TyCon -> Bool +-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is +-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector +-- for 'tyConUnique' would generate unreachable code for every other data +-- constructor of TyCon (see #18026). +isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey +isConstraintKindCon _ = False + isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except during type inference. -} -isConstraintKindCon :: TyCon -> Bool -isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey - -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). -- E.g. True of TYPE k, TYPE (F Int) ===================================== compiler/prelude/TysWiredIn.hs ===================================== @@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon typeSymbolKind = mkTyConTy typeSymbolKindCon constraintKindTyCon :: TyCon +-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon! constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/101fab6ee6cee72b9ffce40e45ebf39466d1c01a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/101fab6ee6cee72b9ffce40e45ebf39466d1c01a You're receiving 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 10 03:12:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 23:12:07 -0400 Subject: [Git][ghc/ghc][master] DmdAnal: No need to attach a StrictSig to DataCon workers Message-ID: <5e8fe40724938_61673f8199536d944210518@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 5 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -614,7 +614,7 @@ data DataConRep -- and *including* all evidence args , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make + -- 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 @@ -715,8 +715,26 @@ filterEqSpec eq_spec instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- 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,Int) +Why? Because the *wrapper* $WMkT is strict (and its unfolding has case +expressions that do the evals) but the *worker* MkT itself is not. If we +pretend it is strict then when we see + case x of y -> MkT y +the simplifier thinks that y is "sure to be evaluated" (because the worker MkT +is strict) and drops the case. No, the workerId MkT is not strict. + +However, the worker does have StrictnessMarks. When the simplifier sees a +pattern + case e of MkT x -> ... +it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's +fine... dataConRepStrictness comes from the data con not from the worker Id. + +Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment dmdTransform env var dmd | isDataConWorkId var -- Data constructor - = dmdTransformDataConSig (idArity var) (idStrictness var) dmd + = dmdTransformDataConSig (idArity var) dmd | gopt Opt_DmdTxDictSel (ae_dflags env), Just _ <- isClassOpId_maybe var -- Dictionary component selector ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -2758,7 +2758,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.Types.Id.Make +See Note [Data-con worker strictness] in GHC.Core.DataCon NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd = postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty -- see Note [Demands from unsaturated function calls] -dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType +dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType -- Same as dmdTransformSig but for a data constructor (worker), -- which has a special kind of demand transformer. -- If the constructor is saturated, we feed the demand on -- the result into the constructor arguments. -dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res)) - (JD { sd = str, ud = abs }) +dmdTransformDataConSig arity (JD { sd = str, ud = abs }) | Just str_dmds <- go_str arity str , Just abs_dmds <- go_abs arity abs - = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res - -- Must remember whether it's a product, hence con_res, not TopRes + = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv | otherwise -- Not saturated = nopDmdType ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con tycon = dataConTyCon data_con -- The representation TyCon wkr_ty = dataConRepType data_con - ----------- Workers for data types -------------- + ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo `setArityInfo` wkr_arity - `setStrictnessInfo` wkr_sig `setCprInfo` mkCprSig wkr_arity (dataConCPR data_con) `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 @@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con -- setNeverLevPoly wkr_arity = dataConRepArity data_con - wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv - -- 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,Int) - -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has - -- case expressions that do the evals) but the *worker* MkT itself is - -- not. If we pretend it is strict then when we see - -- case x of y -> MkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- the worker MkT is strict) and drops the case. No, the workerId - -- MkT is not strict. - -- - -- However, the worker does have StrictnessMarks. When the simplifier - -- sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - ----------- Workers for newtypes -------------- + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5212dfc10414212e42247c2f2dcc45252f7e1d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5212dfc10414212e42247c2f2dcc45252f7e1d2 You're receiving 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 10 03:12:46 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 09 Apr 2020 23:12:46 -0400 Subject: [Git][ghc/ghc][master] Hadrian: fix --summary Message-ID: <5e8fe42ee09fd_6167136dfb9c42134c2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 1 changed file: - hadrian/src/Settings/Builders/RunTest.hs Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -165,7 +165,7 @@ getTestArgs = do brokenTestArgs = concat [ ["--broken-test", t] | t <- brokenTests args ] speedArg = ["-e", "config.speed=" ++ setTestSpeed (testSpeed args)] summaryArg = case testSummary args of - Just filepath -> Just $ "--summary-file " ++ show filepath + Just filepath -> Just $ "--summary-file=" ++ filepath Nothing -> Just $ "--summary-file=testsuite_summary.txt" junitArg = case testJUnit args of Just filepath -> Just $ "--junit=" ++ filepath View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75a185dc2a648ab1f592d401daa5efcacb451c83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75a185dc2a648ab1f592d401daa5efcacb451c83 You're receiving 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 10 03:21:57 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Thu, 09 Apr 2020 23:21:57 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] 13 commits: hadrian: Use --export-dynamic when linking iserv Message-ID: <5e8fe6555fbad_61673f8198ee100c4214953@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 20536990 by Josh Meredith at 2020-04-09T23:21:50-04:00 Implement extensible interface files - - - - - 4b7c99e3 by Josh Meredith at 2020-04-09T23:21:50-04:00 Change expected stdout for hi file Docs tests - - - - - b3a7a09a by Josh Meredith at 2020-04-09T23:21:50-04:00 Add comment subtitle section for BinData - - - - - a2ef8a67 by Josh Meredith at 2020-04-09T23:21:50-04:00 Add some discussion about extensible interfaces to extending_ghc.rst - - - - - 0142093c by Josh Meredith at 2020-04-09T23:21:50-04:00 Link to the extensible interface files wiki page from extending_ghc.rst - - - - - 30 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/TysWiredIn.hs - compiler/utils/Binary.hs - docs/users_guide/extending_ghc.rst - hadrian/src/Settings/Builders/RunTest.hs - hadrian/src/Settings/Packages.hs - includes/rts/storage/Closures.h - libraries/base/Control/Monad/IO/Class.hs - libraries/ghc-compact/tests/all.T - libraries/ghc-compact/tests/compact_gc.hs - rts/Hash.c - rts/Hash.h - rts/StgMiscClosures.cmm - rts/posix/itimer/Pthread.c - rts/sm/CNF.c - rts/sm/Compact.c - testsuite/config/ghc - testsuite/tests/showIface/DocsInHiFile0.stdout - testsuite/tests/showIface/DocsInHiFile1.stdout - utils/iserv/ghc.mk Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -614,7 +614,7 @@ data DataConRep -- and *including* all evidence args , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make + -- 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 @@ -715,8 +715,26 @@ filterEqSpec eq_spec instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- 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,Int) +Why? Because the *wrapper* $WMkT is strict (and its unfolding has case +expressions that do the evals) but the *worker* MkT itself is not. If we +pretend it is strict then when we see + case x of y -> MkT y +the simplifier thinks that y is "sure to be evaluated" (because the worker MkT +is strict) and drops the case. No, the workerId MkT is not strict. + +However, the worker does have StrictnessMarks. When the simplifier sees a +pattern + case e of MkT x -> ... +it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's +fine... dataConRepStrictness comes from the data con not from the worker Id. + +Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment dmdTransform env var dmd | isDataConWorkId var -- Data constructor - = dmdTransformDataConSig (idArity var) (idStrictness var) dmd + = dmdTransformDataConSig (idArity var) dmd | gopt Opt_DmdTxDictSel (ae_dflags env), Just _ <- isClassOpId_maybe var -- Dictionary component selector ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -2758,7 +2758,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.Types.Id.Make +See Note [Data-con worker strictness] in GHC.Core.DataCon NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -45,7 +45,7 @@ module GHC.Core.TyCon( noTcTyConScopedTyVars, -- ** Predicates on TyCons - isAlgTyCon, isVanillaAlgTyCon, + isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon, isClassTyCon, isFamInstTyCon, isFunTyCon, isPrimTyCon, @@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False +-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind. +isConstraintKindCon :: TyCon -> Bool +-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is +-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector +-- for 'tyConUnique' would generate unreachable code for every other data +-- constructor of TyCon (see #18026). +isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey +isConstraintKindCon _ = False + isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except during type inference. -} -isConstraintKindCon :: TyCon -> Bool -isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey - -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). -- E.g. True of TYPE k, TYPE (F Int) ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -147,7 +147,14 @@ module GHC.Driver.Types ( -- * COMPLETE signature CompleteMatch(..), CompleteMatchMap, - mkCompleteMatchMap, extendCompleteMatchMap + mkCompleteMatchMap, extendCompleteMatchMap, + + -- * Exstensible Iface fields + ExtensibleFields(..), FieldName, + emptyExtensibleFields, + readField, readIfaceField, readIfaceFieldWith, + writeField, writeIfaceField, writeIfaceFieldWith, + deleteField, deleteIfaceField, ) where #include "HsVersions.h" @@ -215,8 +222,10 @@ import GHC.Serialized ( Serialized ) import qualified GHC.LanguageExtensions as LangExt import Foreign -import Control.Monad ( guard, liftM, ap ) +import Control.Monad ( guard, liftM, ap, forM, forM_, replicateM ) import Data.IORef +import Data.Map ( Map ) +import qualified Data.Map as Map import Data.Time import Exception import System.FilePath @@ -1090,9 +1099,17 @@ data ModIface_ (phase :: ModIfacePhase) mi_arg_docs :: ArgDocMap, -- ^ Docs on arguments. - mi_final_exts :: !(IfaceBackendExts phase) + mi_final_exts :: !(IfaceBackendExts phase), -- ^ Either `()` or `ModIfaceBackend` for -- a fully instantiated interface. + + 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 + -- internal `Binary` class (increasing compatibility with types + -- using `Name` and `FastString`, such as HIE), this format is + -- chosen over `ByteString`s. } -- | Old-style accessor for whether or not the ModIface came from an hs-boot @@ -1164,6 +1181,9 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_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_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1264,6 +1284,8 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, + mi_ext_fields = emptyExtensibleFields, -- placeholder because this is dealt + -- with specially when the file is read mi_final_exts = ModIfaceBackend { mi_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1307,7 +1329,9 @@ emptyPartialModIface mod mi_doc_hdr = Nothing, mi_decl_docs = emptyDeclDocMap, mi_arg_docs = emptyArgDocMap, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields + } emptyFullModIface :: Module -> ModIface emptyFullModIface mod = @@ -3279,7 +3303,105 @@ phaseForeignLanguage phase = case phase of -- avoid major space leaks. instance (NFData (IfaceBackendExts (phase :: ModIfacePhase)), NFData (IfaceDeclExts (phase :: ModIfacePhase))) => NFData (ModIface_ phase) where rnf (ModIface f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 - f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23) = + f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24) = rnf f1 `seq` rnf f2 `seq` f3 `seq` f4 `seq` f5 `seq` f6 `seq` rnf f7 `seq` f8 `seq` f9 `seq` rnf f10 `seq` rnf f11 `seq` f12 `seq` rnf f13 `seq` rnf f14 `seq` rnf f15 `seq` rnf f16 `seq` f17 `seq` rnf f18 `seq` rnf f19 `seq` f20 `seq` f21 `seq` f22 `seq` rnf f23 + `seq` rnf f24 + +{- +************************************************************************ +* * +\subsection{Extensible Iface Fields} +* * +************************************************************************ +-} + +type FieldName = String + +newtype ExtensibleFields = ExtensibleFields { getExtensibleFields :: (Map FieldName BinData) } + +instance Binary ExtensibleFields where + put_ bh (ExtensibleFields fs) = do + put_ bh (Map.size fs :: Int) + + -- Put the names of each field, and reserve a space + -- for a payload pointer after each name: + header_entries <- forM (Map.toList fs) $ \(name, dat) -> do + put_ bh name + field_p_p <- tellBin 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 + putAt bh field_p_p field_p + seekBin bh field_p + put_ bh dat + + get bh = do + n <- get bh :: IO Int + + -- Get the names and field pointers: + header_entries <- replicateM n $ do + (,) <$> get bh <*> get bh + + -- Seek to and get each field's payload: + fields <- forM header_entries $ \(name, field_p) -> do + seekBin bh field_p + dat <- get bh + return (name, dat) + + return . ExtensibleFields . Map.fromList $ fields + +instance NFData ExtensibleFields where + rnf (ExtensibleFields fs) = rnf fs + +emptyExtensibleFields :: ExtensibleFields +emptyExtensibleFields = ExtensibleFields Map.empty + +-------------------------------------------------------------------------------- +-- | Reading + +readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) +readIfaceField name = readIfaceFieldWith name get + +readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) +readField name = readFieldWith name get + +readIfaceFieldWith :: FieldName -> (BinHandle -> IO a) -> ModIface -> IO (Maybe a) +readIfaceFieldWith name read iface = readFieldWith name read (mi_ext_fields iface) + +readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> + Map.lookup name (getExtensibleFields fields) + +-------------------------------------------------------------------------------- +-- | Writing + +writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface +writeIfaceField name x = writeIfaceFieldWith name (`put_` x) + +writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields +writeField name x = writeFieldWith name (`put_` x) + +writeIfaceFieldWith :: FieldName -> (BinHandle -> IO ()) -> ModIface -> IO ModIface +writeIfaceFieldWith name write iface = do + fields <- writeFieldWith name write (mi_ext_fields iface) + return iface{ mi_ext_fields = fields } + +writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith name write fields = do + bh <- openBinMem (1024 * 1024) + write bh + -- + bd <- handleData bh + return $ ExtensibleFields (Map.insert name bd $ getExtensibleFields fields) + +deleteField :: FieldName -> ExtensibleFields -> ExtensibleFields +deleteField name (ExtensibleFields fs) = ExtensibleFields $ Map.delete name fs + +deleteIfaceField :: FieldName -> ModIface -> ModIface +deleteIfaceField name iface = iface { mi_ext_fields = deleteField name (mi_ext_fields iface) } ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -148,7 +148,15 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do wantedGot "Way" way_descr check_way ppr when (checkHiWay == CheckHiWay) $ errorOnMismatch "mismatched interface file ways" way_descr check_way - getWithUserData ncu bh + + extFields_p <- get bh + + mod_iface <- getWithUserData ncu bh + + seekBin bh extFields_p + extFields <- get bh + + return mod_iface{mi_ext_fields = extFields} -- | This performs a get action after reading the dictionary and symbol @@ -200,8 +208,16 @@ writeBinIface dflags hi_path mod_iface = do let way_descr = getWayDescr dflags put_ bh way_descr + extFields_p_p <- tellBin bh + put_ bh extFields_p_p putWithUserData (debugTraceMsg dflags 3) bh mod_iface + + extFields_p <- tellBin bh + putAt bh extFields_p_p extFields_p + seekBin bh extFields_p + put_ bh (mi_ext_fields mod_iface) + -- And send the result to the file writeBinMem bh hi_path ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Driver.Types import GHC.Types.Basic hiding (SuccessFlag(..)) import GHC.Tc.Utils.Monad +import Binary ( BinData(..) ) import Constants import PrelNames import PrelInfo @@ -83,6 +84,7 @@ import GHC.Driver.Plugins import Control.Monad import Control.Exception import Data.IORef +import Data.Map ( toList ) import System.FilePath import System.Directory @@ -1159,6 +1161,7 @@ pprModIface iface at ModIface{ mi_final_exts = exts } , text "module header:" $$ nest 2 (ppr (mi_doc_hdr iface)) , text "declaration docs:" $$ nest 2 (ppr (mi_decl_docs iface)) , text "arg docs:" $$ nest 2 (ppr (mi_arg_docs iface)) + , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where pp_hsc_src HsBootFile = text "[boot]" @@ -1248,6 +1251,11 @@ pprIfaceAnnotation :: IfaceAnnotation -> SDoc pprIfaceAnnotation (IfaceAnnotation { ifAnnotatedTarget = target, ifAnnotatedValue = serialized }) = ppr target <+> text "annotated by" <+> ppr serialized +pprExtensibleFields :: ExtensibleFields -> SDoc +pprExtensibleFields (ExtensibleFields fs) = vcat . map pprField $ toList fs + where + pprField (name, (BinData size _data)) = text name <+> text "-" <+> ppr size <+> text "bytes" + {- ********************************************************* * * ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -268,7 +268,8 @@ mkIface_ hsc_env mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields } where cmp_rule = comparing ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd = postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty -- see Note [Demands from unsaturated function calls] -dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType +dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType -- Same as dmdTransformSig but for a data constructor (worker), -- which has a special kind of demand transformer. -- If the constructor is saturated, we feed the demand on -- the result into the constructor arguments. -dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res)) - (JD { sd = str, ud = abs }) +dmdTransformDataConSig arity (JD { sd = str, ud = abs }) | Just str_dmds <- go_str arity str , Just abs_dmds <- go_abs arity abs - = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res - -- Must remember whether it's a product, hence con_res, not TopRes + = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv | otherwise -- Not saturated = nopDmdType ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con tycon = dataConTyCon data_con -- The representation TyCon wkr_ty = dataConRepType data_con - ----------- Workers for data types -------------- + ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo `setArityInfo` wkr_arity - `setStrictnessInfo` wkr_sig `setCprInfo` mkCprSig wkr_arity (dataConCPR data_con) `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 @@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con -- setNeverLevPoly wkr_arity = dataConRepArity data_con - wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv - -- 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,Int) - -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has - -- case expressions that do the evals) but the *worker* MkT itself is - -- not. If we pretend it is strict then when we see - -- case x of y -> MkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- the worker MkT is strict) and drops the case. No, the workerId - -- MkT is not strict. - -- - -- However, the worker does have StrictnessMarks. When the simplifier - -- sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - ----------- Workers for newtypes -------------- + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo ===================================== compiler/prelude/TysWiredIn.hs ===================================== @@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon typeSymbolKind = mkTyConTy typeSymbolKindCon constraintKindTyCon :: TyCon +-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon! constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind ===================================== compiler/utils/Binary.hs ===================================== @@ -27,6 +27,8 @@ module Binary {-type-} BinHandle, SymbolTable, Dictionary, + BinData(..), dataHandle, handleData, + openBinMem, -- closeBin, @@ -73,6 +75,7 @@ import Fingerprint import GHC.Types.Basic import GHC.Types.SrcLoc +import Control.DeepSeq import Foreign import Data.Array import Data.ByteString (ByteString) @@ -95,6 +98,44 @@ import GHC.Serialized type BinArray = ForeignPtr Word8 + + +--------------------------------------------------------------- +-- BinData +--------------------------------------------------------------- + +data BinData = BinData Int BinArray + +instance NFData BinData where + rnf (BinData sz _) = rnf sz + +instance Binary BinData where + put_ bh (BinData sz dat) = do + put_ bh sz + putPrim bh sz $ \dest -> + withForeignPtr dat $ \orig -> + copyBytes dest orig sz + -- + get bh = do + sz <- get bh + dat <- mallocForeignPtrBytes sz + getPrim bh sz $ \orig -> + withForeignPtr dat $ \dest -> + copyBytes dest orig sz + return (BinData sz dat) + +dataHandle :: BinData -> IO BinHandle +dataHandle (BinData size bin) = do + ixr <- newFastMutInt + szr <- newFastMutInt + writeFastMutInt ixr 0 + writeFastMutInt szr size + binr <- newIORef bin + return (BinMem noUserData ixr szr binr) + +handleData :: BinHandle -> IO BinData +handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -749,6 +749,18 @@ NOT be invoked with your own modules. In the ``ModIface`` datatype you can find lots of useful information, including the exported definitions and type class instances. +The ``ModIface`` datatype also contains facilities for extending it with extra +data, stored in a ``Map`` of serialised fields, indexed by field names and using +GHC's internal ``Binary`` class. The interface to work with these fields is: + +:: + + readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) + writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface + deleteIfaceField :: FieldName -> ModIface -> ModIface + +To read an interface file from an external tool without linking to GHC, the format +is described at `Extensible Interface Files`_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -165,7 +165,7 @@ getTestArgs = do brokenTestArgs = concat [ ["--broken-test", t] | t <- brokenTests args ] speedArg = ["-e", "config.speed=" ++ setTestSpeed (testSpeed args)] summaryArg = case testSummary args of - Just filepath -> Just $ "--summary-file " ++ show filepath + Just filepath -> Just $ "--summary-file=" ++ filepath Nothing -> Just $ "--summary-file=testsuite_summary.txt" junitArg = case testJUnit args of Just filepath -> Just $ "--junit=" ++ filepath ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -122,6 +122,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , cross ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== includes/rts/storage/Closures.h ===================================== @@ -486,4 +486,7 @@ typedef struct StgCompactNFData_ { StgClosure *result; // Used temporarily to store the result of compaction. Doesn't need to be // a GC root. + struct StgCompactNFData_ *link; + // Used by compacting GC for linking CNFs with threaded hash tables. See + // Note [CNFs in compacting GC] in Compact.c for details. } StgCompactNFData; ===================================== libraries/base/Control/Monad/IO/Class.hs ===================================== @@ -30,8 +30,42 @@ module Control.Monad.IO.Class ( class (Monad m) => MonadIO m where -- | Lift a computation from the 'IO' monad. + -- This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations + -- (i.e. 'IO' is the base monad for the stack). + -- + -- === __Example__ + -- + -- + -- > import Control.Monad.Trans.State -- from the "transformers" library + -- > + -- > printState :: Show s => StateT s IO () + -- > printState = do + -- > state <- get + -- > liftIO $ print state + -- + -- + -- Had we omitted @'liftIO'@, we would have ended up with this error: + -- + -- > • Couldn't match type ‘IO’ with ‘StateT s IO’ + -- > Expected type: StateT s IO () + -- > Actual type: IO () + -- + -- The important part here is the mismatch between @StateT s IO ()@ and @'IO' ()@. + -- + -- Luckily, we know of a function that takes an @'IO' a@ and returns an @(m a)@: @'liftIO'@, + -- enabling us to run the program and see the expected results: + -- + -- @ + -- > evalStateT printState "hello" + -- "hello" + -- + -- > evalStateT printState 3 + -- 3 + -- @ + -- liftIO :: IO a -> m a -- | @since 4.9.0.0 instance MonadIO IO where liftIO = id + ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -1,4 +1,4 @@ -setTestOpts(extra_ways(['sanity'])) +setTestOpts(extra_ways(['sanity', 'compacting_gc'])) test('compact_simple', normal, compile_and_run, ['']) test('compact_loop', normal, compile_and_run, ['']) ===================================== libraries/ghc-compact/tests/compact_gc.hs ===================================== @@ -6,6 +6,8 @@ main = do let m = Map.fromList [(x,show x) | x <- [1..(10000::Int)]] c <- compactWithSharing m print =<< compactSize c - c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c); print =<< compactSize c; return c) c [1..10] + c <- foldM (\c _ -> do c <- compactWithSharing (getCompact c) + print =<< compactSize c + return c) c [1..10] print (length (show (getCompact c))) print =<< compactSize c ===================================== rts/Hash.c ===================================== @@ -444,17 +444,13 @@ freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) void mapHashTable(HashTable *table, void *data, MapHashFn fn) { - long segment; - long index; - HashList *hl; - /* The last bucket with something in it is table->max + table->split - 1 */ - segment = (table->max + table->split - 1) / HSEGSIZE; - index = (table->max + table->split - 1) % HSEGSIZE; + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; while (segment >= 0) { while (index >= 0) { - for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { fn(data, hl->key, hl->data); } index--; @@ -464,6 +460,25 @@ mapHashTable(HashTable *table, void *data, MapHashFn fn) } } +void +mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn) +{ + /* The last bucket with something in it is table->max + table->split - 1 */ + long segment = (table->max + table->split - 1) / HSEGSIZE; + long index = (table->max + table->split - 1) % HSEGSIZE; + + while (segment >= 0) { + while (index >= 0) { + for (HashList *hl = table->dir[segment][index]; hl != NULL; hl = hl->next) { + fn(data, &hl->key, hl->data); + } + index--; + } + segment--; + index = HSEGSIZE - 1; + } +} + /* ----------------------------------------------------------------------------- * When we initialize a hash table, we set up the first segment as well, * initializing all of the first segment's hash buckets to NULL. ===================================== rts/Hash.h ===================================== @@ -34,8 +34,10 @@ int keyCountHashTable (HashTable *table); int keysHashTable(HashTable *table, StgWord keys[], int szKeys); typedef void (*MapHashFn)(void *data, StgWord key, const void *value); +typedef void (*MapHashFnKeys)(void *data, StgWord *key, const void *value); void mapHashTable(HashTable *table, void *data, MapHashFn fn); +void mapHashTableKeys(HashTable *table, void *data, MapHashFnKeys fn); /* Hash table access where the keys are C strings (the strings are * assumed to be allocated by the caller, and mustn't be deallocated ===================================== rts/StgMiscClosures.cmm ===================================== @@ -686,11 +686,11 @@ INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE compaction is in progress and the hash table needs to be scanned by the GC. ------------------------------------------------------------------------- */ -INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_CLEAN object (%p) entered!", R1) never returns; } -INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 8, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") +INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA") () { foreign "C" barf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1) never returns; } ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -110,13 +110,13 @@ static void *itimer_thread_func(void *_handle_tick) timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { - barf("timerfd_create"); + barf("timerfd_create: %s", strerror(errno)); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { - barf("timerfd_settime"); + barf("timerfd_settime: %s", strerror(errno)); } #endif @@ -124,7 +124,7 @@ static void *itimer_thread_func(void *_handle_tick) if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); + barf("Itimer: read(timerfd) failed: %s", strerror(errno)); } } } else { @@ -170,7 +170,7 @@ initTicker (Time interval, TickProc handle_tick) pthread_setname_np(thread, "ghc_ticker"); #endif } else { - barf("Itimer: Failed to spawn thread"); + barf("Itimer: Failed to spawn thread: %s", strerror(errno)); } } @@ -204,7 +204,7 @@ exitTicker (bool wait) // wait for ticker to terminate if necessary if (wait) { if (pthread_join(thread, NULL)) { - sysErrorBelch("Itimer: Failed to join"); + sysErrorBelch("Itimer: Failed to join: %s", strerror(errno)); } closeMutex(&mutex); closeCondition(&start_cond); ===================================== rts/sm/CNF.c ===================================== @@ -381,6 +381,7 @@ compactNew (Capability *cap, StgWord size) self->nursery = block; self->last = block; self->hash = NULL; + self->link = NULL; block->owner = self; ===================================== rts/sm/Compact.c ===================================== @@ -473,6 +473,67 @@ thread_TSO (StgTSO *tso) return (P_)tso + sizeofW(StgTSO); } +/* ---------------------------------------------------------------------------- + Note [CNFs in compacting GC] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CNF hash table keys point outside of the CNF so those need to be threaded + and updated during compaction. After compaction we need to re-visit those + hash tables for re-hashing. The list `nfdata_chain` is used for that + purpose. When we thread keys of a CNF we add the CNF to the list. After + compacting is done we re-visit the CNFs in the list and re-hash their + tables. See also #17937 for more details. + ------------------------------------------------------------------------- */ + +static StgCompactNFData *nfdata_chain = NULL; + +static void +thread_nfdata_hash_key(void *data STG_UNUSED, StgWord *key, const void *value STG_UNUSED) +{ + thread_((void *)key); +} + +static void +add_hash_entry(void *data, StgWord key, const void *value) +{ + HashTable *new_hash = (HashTable *)data; + insertHashTable(new_hash, key, value); +} + +static void +rehash_CNFs(void) +{ + while (nfdata_chain != NULL) { + StgCompactNFData *str = nfdata_chain; + nfdata_chain = str->link; + str->link = NULL; + + HashTable *new_hash = allocHashTable(); + mapHashTable(str->hash, (void*)new_hash, add_hash_entry); + freeHashTable(str->hash, NULL); + str->hash = new_hash; + } +} + +static void +update_fwd_cnf( bdescr *bd ) +{ + while (bd) { + ASSERT(bd->flags & BF_COMPACT); + StgCompactNFData *str = ((StgCompactNFDataBlock*)bd->start)->owner; + + // Thread hash table keys. Values won't be moved as those are inside the + // CNF, and the CNF is a large object and so won't ever move. + if (str->hash) { + mapHashTableKeys(str->hash, NULL, thread_nfdata_hash_key); + ASSERT(str->link == NULL); + str->link = nfdata_chain; + nfdata_chain = str; + } + + bd = bd->link; + } +} static void update_fwd_large( bdescr *bd ) @@ -489,7 +550,6 @@ update_fwd_large( bdescr *bd ) switch (info->type) { case ARR_WORDS: - case COMPACT_NFDATA: // nothing to follow continue; @@ -968,6 +1028,7 @@ compact(StgClosure *static_objects, update_fwd(gc_threads[n]->gens[g].part_list); } update_fwd_large(gen->scavenged_large_objects); + update_fwd_cnf(gen->live_compact_objects); if (g == RtsFlags.GcFlags.generations-1 && gen->old_blocks != NULL) { debugTrace(DEBUG_gc, "update_fwd: %d (compact)", g); update_fwd_compact(gen->old_blocks); @@ -983,4 +1044,8 @@ compact(StgClosure *static_objects, gen->no, gen->n_old_blocks, blocks); gen->n_old_blocks = blocks; } + + // 4. Re-hash hash tables of threaded CNFs. + // See Note [CNFs in compacting GC] above. + rehash_CNFs(); } ===================================== testsuite/config/ghc ===================================== @@ -29,7 +29,9 @@ config.other_ways = ['prof', 'normal_h', 'ext-interp', 'nonmoving', 'nonmoving_thr', - 'nonmoving_thr_ghc'] + 'nonmoving_thr_ghc', + 'compacting_gc', + ] if ghc_with_native_codegen: config.compile_ways.append('optasm') @@ -105,6 +107,7 @@ config.way_flags = { 'nonmoving' : [], 'nonmoving_thr': ['-threaded'], 'nonmoving_thr_ghc': ['+RTS', '-xn', '-N2', '-RTS', '-threaded'], + 'compacting_gc': [], } config.way_rts_flags = { @@ -146,6 +149,7 @@ config.way_rts_flags = { 'nonmoving' : ['-xn'], 'nonmoving_thr' : ['-xn', '-N2'], 'nonmoving_thr_ghc': ['-xn', '-N2'], + 'compacting_gc': ['-c'], } # Useful classes of ways that can be used with only_ways(), omit_ways() and ===================================== testsuite/tests/showIface/DocsInHiFile0.stdout ===================================== @@ -2,3 +2,4 @@ module header: Nothing declaration docs: arg docs: +extensible fields: ===================================== testsuite/tests/showIface/DocsInHiFile1.stdout ===================================== @@ -33,4 +33,4 @@ arg docs: p: 0: " An argument" - +extensible fields: ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e3f6acc45263b6963a5eb508c7883d81970fb999...0142093c65f35415e80a1e720fddf73f01ad0482 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e3f6acc45263b6963a5eb508c7883d81970fb999...0142093c65f35415e80a1e720fddf73f01ad0482 You're receiving 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 10 05:25:25 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 10 Apr 2020 01:25:25 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/hadrian-no-export-dynamic-on-darwin Message-ID: <5e9003457ede9_616713503ee04222747@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/hadrian-no-export-dynamic-on-darwin at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/hadrian-no-export-dynamic-on-darwin You're receiving 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 10 05:28:08 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Fri, 10 Apr 2020 01:28:08 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] Add discussion about FieldName formats for extensible fields Message-ID: <5e9003e852a86_61673f8199536d9442259ed@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: 46f80417 by Josh Meredith at 2020-04-10T15:27:49+10:00 Add discussion about FieldName formats for extensible fields - - - - - 1 changed file: - docs/users_guide/extending_ghc.rst Changes: ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -759,6 +759,22 @@ GHC's internal ``Binary`` class. The interface to work with these fields is: writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface deleteIfaceField :: FieldName -> ModIface -> ModIface +The ``FieldName`` is open-ended, but typically it should contain the producing +package name, a version number, and the actual field name. For example, a GHC +Core field might be named like: + +:: + + ghc-n.n.n/core + +In this example, the version would probably correspond to the package name, but +a field that changes slower than the package version might associate the version +with the field: + +:: + + example/field-n + To read an interface file from an external tool without linking to GHC, the format is described at `Extensible Interface Files`_. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/46f8041767f3a3a64035cfa4a97f1505c1e5566b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/46f8041767f3a3a64035cfa4a97f1505c1e5566b You're receiving 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 10 09:15:05 2020 From: gitlab at gitlab.haskell.org (Peter Trommler) Date: Fri, 10 Apr 2020 05:15:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T11531-fixup Message-ID: <5e90391919bf6_6167134ebbc442535b2@gitlab.haskell.org.mail> Peter Trommler pushed new branch wip/T11531-fixup at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T11531-fixup You're receiving 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 10 10:09:29 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Fri, 10 Apr 2020 06:09:29 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] Change extensible field name version advice Message-ID: <5e9045d9933d2_61677c82e0c4260031@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: ee5e88f9 by Josh Meredith at 2020-04-10T20:09:17+10:00 Change extensible field name version advice - - - - - 1 changed file: - docs/users_guide/extending_ghc.rst Changes: ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -760,20 +760,19 @@ GHC's internal ``Binary`` class. The interface to work with these fields is: deleteIfaceField :: FieldName -> ModIface -> ModIface The ``FieldName`` is open-ended, but typically it should contain the producing -package name, a version number, and the actual field name. For example, a GHC -Core field might be named like: +package name, along with the actual field name. Then, the version number can either +be attached to the serialised data for that field, or in cases where multiple versions +of a field could exist in the same interface file, included in the field name. -:: - - ghc-n.n.n/core - -In this example, the version would probably correspond to the package name, but -a field that changes slower than the package version might associate the version -with the field: +Depending on if the field version advances with the package version, or independently, +the version can be attached to either the package name or the field name. Examples of +each case: :: - example/field-n + package/field + ghc-n.n.n/core + package/field-n To read an interface file from an external tool without linking to GHC, the format is described at `Extensible Interface Files`_. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee5e88f9e131b4949dd2326689c02490322c1f38 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee5e88f9e131b4949dd2326689c02490322c1f38 You're receiving 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 10 11:15:08 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Fri, 10 Apr 2020 07:15:08 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] Implement extensible interface files Message-ID: <5e90553cd6dd8_6167134ebbc442739e1@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: b03ae53c by Josh Meredith at 2020-04-10T21:13:39+10:00 Implement extensible interface files - - - - - 8 changed files: - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/utils/Binary.hs - docs/users_guide/extending_ghc.rst - testsuite/tests/showIface/DocsInHiFile0.stdout - testsuite/tests/showIface/DocsInHiFile1.stdout Changes: ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -147,7 +147,14 @@ module GHC.Driver.Types ( -- * COMPLETE signature CompleteMatch(..), CompleteMatchMap, - mkCompleteMatchMap, extendCompleteMatchMap + mkCompleteMatchMap, extendCompleteMatchMap, + + -- * Exstensible Iface fields + ExtensibleFields(..), FieldName, + emptyExtensibleFields, + readField, readIfaceField, readIfaceFieldWith, + writeField, writeIfaceField, writeIfaceFieldWith, + deleteField, deleteIfaceField, ) where #include "HsVersions.h" @@ -215,8 +222,10 @@ import GHC.Serialized ( Serialized ) import qualified GHC.LanguageExtensions as LangExt import Foreign -import Control.Monad ( guard, liftM, ap ) +import Control.Monad ( guard, liftM, ap, forM, forM_, replicateM ) import Data.IORef +import Data.Map ( Map ) +import qualified Data.Map as Map import Data.Time import Exception import System.FilePath @@ -1090,9 +1099,17 @@ data ModIface_ (phase :: ModIfacePhase) mi_arg_docs :: ArgDocMap, -- ^ Docs on arguments. - mi_final_exts :: !(IfaceBackendExts phase) + mi_final_exts :: !(IfaceBackendExts phase), -- ^ Either `()` or `ModIfaceBackend` for -- a fully instantiated interface. + + 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 + -- internal `Binary` class (increasing compatibility with types + -- using `Name` and `FastString`, such as HIE), this format is + -- chosen over `ByteString`s. } -- | Old-style accessor for whether or not the ModIface came from an hs-boot @@ -1164,6 +1181,9 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_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_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1264,6 +1284,8 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, + mi_ext_fields = emptyExtensibleFields, -- placeholder because this is dealt + -- with specially when the file is read mi_final_exts = ModIfaceBackend { mi_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1307,7 +1329,9 @@ emptyPartialModIface mod mi_doc_hdr = Nothing, mi_decl_docs = emptyDeclDocMap, mi_arg_docs = emptyArgDocMap, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields + } emptyFullModIface :: Module -> ModIface emptyFullModIface mod = @@ -3279,7 +3303,105 @@ phaseForeignLanguage phase = case phase of -- avoid major space leaks. instance (NFData (IfaceBackendExts (phase :: ModIfacePhase)), NFData (IfaceDeclExts (phase :: ModIfacePhase))) => NFData (ModIface_ phase) where rnf (ModIface f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 - f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23) = + f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24) = rnf f1 `seq` rnf f2 `seq` f3 `seq` f4 `seq` f5 `seq` f6 `seq` rnf f7 `seq` f8 `seq` f9 `seq` rnf f10 `seq` rnf f11 `seq` f12 `seq` rnf f13 `seq` rnf f14 `seq` rnf f15 `seq` rnf f16 `seq` f17 `seq` rnf f18 `seq` rnf f19 `seq` f20 `seq` f21 `seq` f22 `seq` rnf f23 + `seq` rnf f24 + +{- +************************************************************************ +* * +\subsection{Extensible Iface Fields} +* * +************************************************************************ +-} + +type FieldName = String + +newtype ExtensibleFields = ExtensibleFields { getExtensibleFields :: (Map FieldName BinData) } + +instance Binary ExtensibleFields where + put_ bh (ExtensibleFields fs) = do + put_ bh (Map.size fs :: Int) + + -- Put the names of each field, and reserve a space + -- for a payload pointer after each name: + header_entries <- forM (Map.toList fs) $ \(name, dat) -> do + put_ bh name + field_p_p <- tellBin 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 + putAt bh field_p_p field_p + seekBin bh field_p + put_ bh dat + + get bh = do + n <- get bh :: IO Int + + -- Get the names and field pointers: + header_entries <- replicateM n $ do + (,) <$> get bh <*> get bh + + -- Seek to and get each field's payload: + fields <- forM header_entries $ \(name, field_p) -> do + seekBin bh field_p + dat <- get bh + return (name, dat) + + return . ExtensibleFields . Map.fromList $ fields + +instance NFData ExtensibleFields where + rnf (ExtensibleFields fs) = rnf fs + +emptyExtensibleFields :: ExtensibleFields +emptyExtensibleFields = ExtensibleFields Map.empty + +-------------------------------------------------------------------------------- +-- | Reading + +readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) +readIfaceField name = readIfaceFieldWith name get + +readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) +readField name = readFieldWith name get + +readIfaceFieldWith :: FieldName -> (BinHandle -> IO a) -> ModIface -> IO (Maybe a) +readIfaceFieldWith name read iface = readFieldWith name read (mi_ext_fields iface) + +readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> + Map.lookup name (getExtensibleFields fields) + +-------------------------------------------------------------------------------- +-- | Writing + +writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface +writeIfaceField name x = writeIfaceFieldWith name (`put_` x) + +writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields +writeField name x = writeFieldWith name (`put_` x) + +writeIfaceFieldWith :: FieldName -> (BinHandle -> IO ()) -> ModIface -> IO ModIface +writeIfaceFieldWith name write iface = do + fields <- writeFieldWith name write (mi_ext_fields iface) + return iface{ mi_ext_fields = fields } + +writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith name write fields = do + bh <- openBinMem (1024 * 1024) + write bh + -- + bd <- handleData bh + return $ ExtensibleFields (Map.insert name bd $ getExtensibleFields fields) + +deleteField :: FieldName -> ExtensibleFields -> ExtensibleFields +deleteField name (ExtensibleFields fs) = ExtensibleFields $ Map.delete name fs + +deleteIfaceField :: FieldName -> ModIface -> ModIface +deleteIfaceField name iface = iface { mi_ext_fields = deleteField name (mi_ext_fields iface) } ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -148,7 +148,15 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do wantedGot "Way" way_descr check_way ppr when (checkHiWay == CheckHiWay) $ errorOnMismatch "mismatched interface file ways" way_descr check_way - getWithUserData ncu bh + + extFields_p <- get bh + + mod_iface <- getWithUserData ncu bh + + seekBin bh extFields_p + extFields <- get bh + + return mod_iface{mi_ext_fields = extFields} -- | This performs a get action after reading the dictionary and symbol @@ -200,8 +208,16 @@ writeBinIface dflags hi_path mod_iface = do let way_descr = getWayDescr dflags put_ bh way_descr + extFields_p_p <- tellBin bh + put_ bh extFields_p_p putWithUserData (debugTraceMsg dflags 3) bh mod_iface + + extFields_p <- tellBin bh + putAt bh extFields_p_p extFields_p + seekBin bh extFields_p + put_ bh (mi_ext_fields mod_iface) + -- And send the result to the file writeBinMem bh hi_path ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Driver.Types import GHC.Types.Basic hiding (SuccessFlag(..)) import GHC.Tc.Utils.Monad +import Binary ( BinData(..) ) import Constants import PrelNames import PrelInfo @@ -83,6 +84,7 @@ import GHC.Driver.Plugins import Control.Monad import Control.Exception import Data.IORef +import Data.Map ( toList ) import System.FilePath import System.Directory @@ -1159,6 +1161,7 @@ pprModIface iface at ModIface{ mi_final_exts = exts } , text "module header:" $$ nest 2 (ppr (mi_doc_hdr iface)) , text "declaration docs:" $$ nest 2 (ppr (mi_decl_docs iface)) , text "arg docs:" $$ nest 2 (ppr (mi_arg_docs iface)) + , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where pp_hsc_src HsBootFile = text "[boot]" @@ -1248,6 +1251,11 @@ pprIfaceAnnotation :: IfaceAnnotation -> SDoc pprIfaceAnnotation (IfaceAnnotation { ifAnnotatedTarget = target, ifAnnotatedValue = serialized }) = ppr target <+> text "annotated by" <+> ppr serialized +pprExtensibleFields :: ExtensibleFields -> SDoc +pprExtensibleFields (ExtensibleFields fs) = vcat . map pprField $ toList fs + where + pprField (name, (BinData size _data)) = text name <+> text "-" <+> ppr size <+> text "bytes" + {- ********************************************************* * * ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -268,7 +268,8 @@ mkIface_ hsc_env mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields } where cmp_rule = comparing ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/utils/Binary.hs ===================================== @@ -27,6 +27,8 @@ module Binary {-type-} BinHandle, SymbolTable, Dictionary, + BinData(..), dataHandle, handleData, + openBinMem, -- closeBin, @@ -73,6 +75,7 @@ import Fingerprint import GHC.Types.Basic import GHC.Types.SrcLoc +import Control.DeepSeq import Foreign import Data.Array import Data.ByteString (ByteString) @@ -95,6 +98,44 @@ import GHC.Serialized type BinArray = ForeignPtr Word8 + + +--------------------------------------------------------------- +-- BinData +--------------------------------------------------------------- + +data BinData = BinData Int BinArray + +instance NFData BinData where + rnf (BinData sz _) = rnf sz + +instance Binary BinData where + put_ bh (BinData sz dat) = do + put_ bh sz + putPrim bh sz $ \dest -> + withForeignPtr dat $ \orig -> + copyBytes dest orig sz + -- + get bh = do + sz <- get bh + dat <- mallocForeignPtrBytes sz + getPrim bh sz $ \orig -> + withForeignPtr dat $ \dest -> + copyBytes dest orig sz + return (BinData sz dat) + +dataHandle :: BinData -> IO BinHandle +dataHandle (BinData size bin) = do + ixr <- newFastMutInt + szr <- newFastMutInt + writeFastMutInt ixr 0 + writeFastMutInt szr size + binr <- newIORef bin + return (BinMem noUserData ixr szr binr) + +handleData :: BinHandle -> IO BinData +handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -749,6 +749,33 @@ NOT be invoked with your own modules. In the ``ModIface`` datatype you can find lots of useful information, including the exported definitions and type class instances. +The ``ModIface`` datatype also contains facilities for extending it with extra +data, stored in a ``Map`` of serialised fields, indexed by field names and using +GHC's internal ``Binary`` class. The interface to work with these fields is: + +:: + + readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) + writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface + deleteIfaceField :: FieldName -> ModIface -> ModIface + +The ``FieldName`` is open-ended, but typically it should contain the producing +package name, along with the actual field name. Then, the version number can either +be attached to the serialised data for that field, or in cases where multiple versions +of a field could exist in the same interface file, included in the field name. + +Depending on if the field version advances with the package version, or independently, +the version can be attached to either the package name or the field name. Examples of +each case: + +:: + + package/field + ghc-n.n.n/core + package/field-n + +To read an interface file from an external tool without linking to GHC, the format +is described at `Extensible Interface Files`_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ ===================================== testsuite/tests/showIface/DocsInHiFile0.stdout ===================================== @@ -2,3 +2,4 @@ module header: Nothing declaration docs: arg docs: +extensible fields: ===================================== testsuite/tests/showIface/DocsInHiFile1.stdout ===================================== @@ -33,4 +33,4 @@ arg docs: p: 0: " An argument" - +extensible fields: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b03ae53c8c455bd665c701fef51bd8813f38e6c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b03ae53c8c455bd665c701fef51bd8813f38e6c9 You're receiving 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 10 11:45:24 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 10 Apr 2020 07:45:24 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 13 commits: simplifier: Kill off ufKeenessFactor Message-ID: <5e905c5479f4_61677c82e0c427853d@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 33f9a555 by Ömer Sinan Ağacan at 2020-04-10T13:02:10+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9a32ab1abbe3eb1b6f6e9f83bbf928ee04d316f9...33f9a555bf9c968908124fc6c5143d9a758d6fb8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9a32ab1abbe3eb1b6f6e9f83bbf928ee04d316f9...33f9a555bf9c968908124fc6c5143d9a758d6fb8 You're receiving 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 10 15:48:25 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 10 Apr 2020 11:48:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add an example to liftIO and explain its purpose Message-ID: <5e9095493fd7b_61673f8199536d944330354@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - 7ac4eba1 by Peter Trommler at 2020-04-10T11:48:17-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 14 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/TysWiredIn.hs - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/Control/Monad/IO/Class.hs - testsuite/driver/testlib.py - testsuite/tests/ghci/linking/all.T - testsuite/tests/hiefile/should_compile/all.T - testsuite/tests/perf/compiler/all.T Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -614,7 +614,7 @@ data DataConRep -- and *including* all evidence args , dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys - -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make + -- 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 @@ -715,8 +715,26 @@ filterEqSpec eq_spec instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) -{- Note [Bangs on data constructor arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- 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,Int) +Why? Because the *wrapper* $WMkT is strict (and its unfolding has case +expressions that do the evals) but the *worker* MkT itself is not. If we +pretend it is strict then when we see + case x of y -> MkT y +the simplifier thinks that y is "sure to be evaluated" (because the worker MkT +is strict) and drops the case. No, the workerId MkT is not strict. + +However, the worker does have StrictnessMarks. When the simplifier sees a +pattern + case e of MkT x -> ... +it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's +fine... dataConRepStrictness comes from the data con not from the worker Id. + +Note [Bangs on data constructor arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT !Int {-# UNPACK #-} !Int Bool ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment dmdTransform env var dmd | isDataConWorkId var -- Data constructor - = dmdTransformDataConSig (idArity var) (idStrictness var) dmd + = dmdTransformDataConSig (idArity var) dmd | gopt Opt_DmdTxDictSel (ae_dflags env), Just _ <- isClassOpId_maybe var -- Dictionary component selector ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -2758,7 +2758,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.Types.Id.Make +See Note [Data-con worker strictness] in GHC.Core.DataCon NB: simplLamBndrs preserves this eval info ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -45,7 +45,7 @@ module GHC.Core.TyCon( noTcTyConScopedTyVars, -- ** Predicates on TyCons - isAlgTyCon, isVanillaAlgTyCon, + isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon, isClassTyCon, isFamInstTyCon, isFunTyCon, isPrimTyCon, @@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False +-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind. +isConstraintKindCon :: TyCon -> Bool +-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is +-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector +-- for 'tyConUnique' would generate unreachable code for every other data +-- constructor of TyCon (see #18026). +isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey +isConstraintKindCon _ = False + isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except during type inference. -} -isConstraintKindCon :: TyCon -> Bool -isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey - -- | Tests whether the given kind (which should look like @TYPE x@) -- is something other than a constructor tree (that is, constructors at every node). -- E.g. True of TYPE k, TYPE (F Int) ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd = postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty -- see Note [Demands from unsaturated function calls] -dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType +dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType -- Same as dmdTransformSig but for a data constructor (worker), -- which has a special kind of demand transformer. -- If the constructor is saturated, we feed the demand on -- the result into the constructor arguments. -dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res)) - (JD { sd = str, ud = abs }) +dmdTransformDataConSig arity (JD { sd = str, ud = abs }) | Just str_dmds <- go_str arity str , Just abs_dmds <- go_abs arity abs - = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res - -- Must remember whether it's a product, hence con_res, not TopRes + = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv | otherwise -- Not saturated = nopDmdType ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con tycon = dataConTyCon data_con -- The representation TyCon wkr_ty = dataConRepType data_con - ----------- Workers for data types -------------- + ----------- Workers for data types -------------- alg_wkr_info = noCafIdInfo `setArityInfo` wkr_arity - `setStrictnessInfo` wkr_sig `setCprInfo` mkCprSig wkr_arity (dataConCPR data_con) `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 @@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con -- setNeverLevPoly wkr_arity = dataConRepArity data_con - wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv - -- 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,Int) - -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has - -- case expressions that do the evals) but the *worker* MkT itself is - -- not. If we pretend it is strict then when we see - -- case x of y -> MkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- the worker MkT is strict) and drops the case. No, the workerId - -- MkT is not strict. - -- - -- However, the worker does have StrictnessMarks. When the simplifier - -- sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - ----------- Workers for newtypes -------------- + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo ===================================== compiler/prelude/TysWiredIn.hs ===================================== @@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon typeSymbolKind = mkTyConTy typeSymbolKindCon constraintKindTyCon :: TyCon +-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon! constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -165,7 +165,7 @@ getTestArgs = do brokenTestArgs = concat [ ["--broken-test", t] | t <- brokenTests args ] speedArg = ["-e", "config.speed=" ++ setTestSpeed (testSpeed args)] summaryArg = case testSummary args of - Just filepath -> Just $ "--summary-file " ++ show filepath + Just filepath -> Just $ "--summary-file=" ++ filepath Nothing -> Just $ "--summary-file=testsuite_summary.txt" junitArg = case testJUnit args of Just filepath -> Just $ "--junit=" ++ filepath ===================================== libraries/base/Control/Monad/IO/Class.hs ===================================== @@ -30,8 +30,42 @@ module Control.Monad.IO.Class ( class (Monad m) => MonadIO m where -- | Lift a computation from the 'IO' monad. + -- This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations + -- (i.e. 'IO' is the base monad for the stack). + -- + -- === __Example__ + -- + -- + -- > import Control.Monad.Trans.State -- from the "transformers" library + -- > + -- > printState :: Show s => StateT s IO () + -- > printState = do + -- > state <- get + -- > liftIO $ print state + -- + -- + -- Had we omitted @'liftIO'@, we would have ended up with this error: + -- + -- > • Couldn't match type ‘IO’ with ‘StateT s IO’ + -- > Expected type: StateT s IO () + -- > Actual type: IO () + -- + -- The important part here is the mismatch between @StateT s IO ()@ and @'IO' ()@. + -- + -- Luckily, we know of a function that takes an @'IO' a@ and returns an @(m a)@: @'liftIO'@, + -- enabling us to run the program and see the expected results: + -- + -- @ + -- > evalStateT printState "hello" + -- "hello" + -- + -- > evalStateT printState 3 + -- 3 + -- @ + -- liftIO :: IO a -> m a -- | @since 4.9.0.0 instance MonadIO IO where liftIO = id + ===================================== testsuite/driver/testlib.py ===================================== @@ -116,6 +116,12 @@ def expect_fail( name, opts ): # future. opts.expect = 'fail'; +def no_lint( name, opts ): + """Disable Core, STG and Cmm lints. Useful when testing compiler perf.""" + opts.compiler_always_flags = \ + [opt for opt in opts.compiler_always_flags \ + if opt not in ['-dcore-lint', '-dstg-lint', '-dcmm-lint']] + def reqlib( lib ): return lambda name, opts, l=lib: _reqlib (name, opts, l ) ===================================== testsuite/tests/ghci/linking/all.T ===================================== @@ -46,7 +46,8 @@ test('T3333', test('T11531', [extra_files(['T11531.hs', 'T11531.c', 'T11531.h']), unless(doing_ghci, skip), - unless(opsys('linux'), skip)], + unless(opsys('linux'), skip), + fragile(11531)], makefile_test, ['T11531']) test('T14708', ===================================== testsuite/tests/hiefile/should_compile/all.T ===================================== @@ -1,6 +1,12 @@ test('hie001', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) -test('hie002', collect_compiler_stats('bytes allocated',10), - compile, ['-fno-code -fwrite-ide-info']) +test('hie002', + [# Allocation numbers unstable on 32-bit, skip: + when(wordsize(32), skip), + # No linting in perf tests: + no_lint, + collect_compiler_stats('bytes allocated',10)], + compile, + ['-fno-code -fwrite-ide-info']) test('hie003', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie004', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie005', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -1,10 +1,5 @@ # Tests that call 'collect_compiler_stats' are skipped when debugging is on. # See testsuite/driver/testlib.py. - -def no_lint(name, opts): - opts.compiler_always_flags = \ - [opt for opt in opts.compiler_always_flags if opt != '-dcore-lint' and opt != '-dcmm-lint'] - setTestOpts(no_lint) test('T1969', View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a829409461c65ca783bb93c7fc1b5978ba33ecf...7ac4eba1ab1c11c0dc079bb1c68e103675cb6c49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a829409461c65ca783bb93c7fc1b5978ba33ecf...7ac4eba1ab1c11c0dc079bb1c68e103675cb6c49 You're receiving 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 10 16:48:41 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Fri, 10 Apr 2020 12:48:41 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Fix T6145 (ConPatIn became ConPat) Message-ID: <5e90a36940298_616776d1c744337079@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 9df7797f by Cale Gibbard at 2020-04-10T12:48:34-04:00 Fix T6145 (ConPatIn became ConPat) - - - - - 1 changed file: - testsuite/tests/ghc-api/T6145.hs Changes: ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9df7797f79bd8e138820e16f550525334080cb89 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9df7797f79bd8e138820e16f550525334080cb89 You're receiving 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 10 23:29:03 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 10 Apr 2020 19:29:03 -0400 Subject: [Git][ghc/ghc][master] testsuite: Move no_lint to the top level, tweak hie002 Message-ID: <5e91013fc3849_616776d1c74437799e@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - 3 changed files: - testsuite/driver/testlib.py - testsuite/tests/hiefile/should_compile/all.T - testsuite/tests/perf/compiler/all.T Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -116,6 +116,12 @@ def expect_fail( name, opts ): # future. opts.expect = 'fail'; +def no_lint( name, opts ): + """Disable Core, STG and Cmm lints. Useful when testing compiler perf.""" + opts.compiler_always_flags = \ + [opt for opt in opts.compiler_always_flags \ + if opt not in ['-dcore-lint', '-dstg-lint', '-dcmm-lint']] + def reqlib( lib ): return lambda name, opts, l=lib: _reqlib (name, opts, l ) ===================================== testsuite/tests/hiefile/should_compile/all.T ===================================== @@ -1,6 +1,12 @@ test('hie001', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) -test('hie002', collect_compiler_stats('bytes allocated',10), - compile, ['-fno-code -fwrite-ide-info']) +test('hie002', + [# Allocation numbers unstable on 32-bit, skip: + when(wordsize(32), skip), + # No linting in perf tests: + no_lint, + collect_compiler_stats('bytes allocated',10)], + compile, + ['-fno-code -fwrite-ide-info']) test('hie003', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie004', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie005', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -1,10 +1,5 @@ # Tests that call 'collect_compiler_stats' are skipped when debugging is on. # See testsuite/driver/testlib.py. - -def no_lint(name, opts): - opts.compiler_always_flags = \ - [opt for opt in opts.compiler_always_flags if opt != '-dcore-lint' and opt != '-dcmm-lint'] - setTestOpts(no_lint) test('T1969', View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/723062edf6191084a99787d3f235183cf6b7d051 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/723062edf6191084a99787d3f235183cf6b7d051 You're receiving 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 10 23:29:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 10 Apr 2020 19:29:43 -0400 Subject: [Git][ghc/ghc][master] Testsuite: mark T11531 fragile Message-ID: <5e9101672050b_6167e4e49b44382466@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 1 changed file: - testsuite/tests/ghci/linking/all.T Changes: ===================================== testsuite/tests/ghci/linking/all.T ===================================== @@ -46,7 +46,8 @@ test('T3333', test('T11531', [extra_files(['T11531.hs', 'T11531.c', 'T11531.h']), unless(doing_ghci, skip), - unless(opsys('linux'), skip)], + unless(opsys('linux'), skip), + fragile(11531)], makefile_test, ['T11531']) test('T14708', View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcafaa82a0223afd5d103e052ab9a097a676e5ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcafaa82a0223afd5d103e052ab9a097a676e5ea You're receiving 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 11 03:37:12 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Fri, 10 Apr 2020 23:37:12 -0400 Subject: [Git][ghc/ghc][wip/extensible-interface-files] 3 commits: testsuite: Move no_lint to the top level, tweak hie002 Message-ID: <5e913b68a4894_6167136dfb9c4399640@gitlab.haskell.org.mail> Josh Meredith pushed to branch wip/extensible-interface-files at Glasgow Haskell Compiler / GHC Commits: 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - bcf72afe by Josh Meredith at 2020-04-10T23:37:08-04:00 Implement extensible interface files - - - - - 12 changed files: - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/utils/Binary.hs - docs/users_guide/extending_ghc.rst - testsuite/driver/testlib.py - testsuite/tests/ghci/linking/all.T - testsuite/tests/hiefile/should_compile/all.T - testsuite/tests/perf/compiler/all.T - testsuite/tests/showIface/DocsInHiFile0.stdout - testsuite/tests/showIface/DocsInHiFile1.stdout Changes: ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -147,7 +147,14 @@ module GHC.Driver.Types ( -- * COMPLETE signature CompleteMatch(..), CompleteMatchMap, - mkCompleteMatchMap, extendCompleteMatchMap + mkCompleteMatchMap, extendCompleteMatchMap, + + -- * Exstensible Iface fields + ExtensibleFields(..), FieldName, + emptyExtensibleFields, + readField, readIfaceField, readIfaceFieldWith, + writeField, writeIfaceField, writeIfaceFieldWith, + deleteField, deleteIfaceField, ) where #include "HsVersions.h" @@ -215,8 +222,10 @@ import GHC.Serialized ( Serialized ) import qualified GHC.LanguageExtensions as LangExt import Foreign -import Control.Monad ( guard, liftM, ap ) +import Control.Monad ( guard, liftM, ap, forM, forM_, replicateM ) import Data.IORef +import Data.Map ( Map ) +import qualified Data.Map as Map import Data.Time import Exception import System.FilePath @@ -1090,9 +1099,17 @@ data ModIface_ (phase :: ModIfacePhase) mi_arg_docs :: ArgDocMap, -- ^ Docs on arguments. - mi_final_exts :: !(IfaceBackendExts phase) + mi_final_exts :: !(IfaceBackendExts phase), -- ^ Either `()` or `ModIfaceBackend` for -- a fully instantiated interface. + + 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 + -- internal `Binary` class (increasing compatibility with types + -- using `Name` and `FastString`, such as HIE), this format is + -- chosen over `ByteString`s. } -- | Old-style accessor for whether or not the ModIface came from an hs-boot @@ -1164,6 +1181,9 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_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_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1264,6 +1284,8 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, + mi_ext_fields = emptyExtensibleFields, -- placeholder because this is dealt + -- with specially when the file is read mi_final_exts = ModIfaceBackend { mi_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1307,7 +1329,9 @@ emptyPartialModIface mod mi_doc_hdr = Nothing, mi_decl_docs = emptyDeclDocMap, mi_arg_docs = emptyArgDocMap, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields + } emptyFullModIface :: Module -> ModIface emptyFullModIface mod = @@ -3279,7 +3303,105 @@ phaseForeignLanguage phase = case phase of -- avoid major space leaks. instance (NFData (IfaceBackendExts (phase :: ModIfacePhase)), NFData (IfaceDeclExts (phase :: ModIfacePhase))) => NFData (ModIface_ phase) where rnf (ModIface f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 - f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23) = + f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24) = rnf f1 `seq` rnf f2 `seq` f3 `seq` f4 `seq` f5 `seq` f6 `seq` rnf f7 `seq` f8 `seq` f9 `seq` rnf f10 `seq` rnf f11 `seq` f12 `seq` rnf f13 `seq` rnf f14 `seq` rnf f15 `seq` rnf f16 `seq` f17 `seq` rnf f18 `seq` rnf f19 `seq` f20 `seq` f21 `seq` f22 `seq` rnf f23 + `seq` rnf f24 + +{- +************************************************************************ +* * +\subsection{Extensible Iface Fields} +* * +************************************************************************ +-} + +type FieldName = String + +newtype ExtensibleFields = ExtensibleFields { getExtensibleFields :: (Map FieldName BinData) } + +instance Binary ExtensibleFields where + put_ bh (ExtensibleFields fs) = do + put_ bh (Map.size fs :: Int) + + -- Put the names of each field, and reserve a space + -- for a payload pointer after each name: + header_entries <- forM (Map.toList fs) $ \(name, dat) -> do + put_ bh name + field_p_p <- tellBin 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 + putAt bh field_p_p field_p + seekBin bh field_p + put_ bh dat + + get bh = do + n <- get bh :: IO Int + + -- Get the names and field pointers: + header_entries <- replicateM n $ do + (,) <$> get bh <*> get bh + + -- Seek to and get each field's payload: + fields <- forM header_entries $ \(name, field_p) -> do + seekBin bh field_p + dat <- get bh + return (name, dat) + + return . ExtensibleFields . Map.fromList $ fields + +instance NFData ExtensibleFields where + rnf (ExtensibleFields fs) = rnf fs + +emptyExtensibleFields :: ExtensibleFields +emptyExtensibleFields = ExtensibleFields Map.empty + +-------------------------------------------------------------------------------- +-- | Reading + +readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) +readIfaceField name = readIfaceFieldWith name get + +readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) +readField name = readFieldWith name get + +readIfaceFieldWith :: FieldName -> (BinHandle -> IO a) -> ModIface -> IO (Maybe a) +readIfaceFieldWith name read iface = readFieldWith name read (mi_ext_fields iface) + +readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> + Map.lookup name (getExtensibleFields fields) + +-------------------------------------------------------------------------------- +-- | Writing + +writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface +writeIfaceField name x = writeIfaceFieldWith name (`put_` x) + +writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields +writeField name x = writeFieldWith name (`put_` x) + +writeIfaceFieldWith :: FieldName -> (BinHandle -> IO ()) -> ModIface -> IO ModIface +writeIfaceFieldWith name write iface = do + fields <- writeFieldWith name write (mi_ext_fields iface) + return iface{ mi_ext_fields = fields } + +writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith name write fields = do + bh <- openBinMem (1024 * 1024) + write bh + -- + bd <- handleData bh + return $ ExtensibleFields (Map.insert name bd $ getExtensibleFields fields) + +deleteField :: FieldName -> ExtensibleFields -> ExtensibleFields +deleteField name (ExtensibleFields fs) = ExtensibleFields $ Map.delete name fs + +deleteIfaceField :: FieldName -> ModIface -> ModIface +deleteIfaceField name iface = iface { mi_ext_fields = deleteField name (mi_ext_fields iface) } ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -148,7 +148,15 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do wantedGot "Way" way_descr check_way ppr when (checkHiWay == CheckHiWay) $ errorOnMismatch "mismatched interface file ways" way_descr check_way - getWithUserData ncu bh + + extFields_p <- get bh + + mod_iface <- getWithUserData ncu bh + + seekBin bh extFields_p + extFields <- get bh + + return mod_iface{mi_ext_fields = extFields} -- | This performs a get action after reading the dictionary and symbol @@ -200,8 +208,16 @@ writeBinIface dflags hi_path mod_iface = do let way_descr = getWayDescr dflags put_ bh way_descr + extFields_p_p <- tellBin bh + put_ bh extFields_p_p putWithUserData (debugTraceMsg dflags 3) bh mod_iface + + extFields_p <- tellBin bh + putAt bh extFields_p_p extFields_p + seekBin bh extFields_p + put_ bh (mi_ext_fields mod_iface) + -- And send the result to the file writeBinMem bh hi_path ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Driver.Types import GHC.Types.Basic hiding (SuccessFlag(..)) import GHC.Tc.Utils.Monad +import Binary ( BinData(..) ) import Constants import PrelNames import PrelInfo @@ -83,6 +84,7 @@ import GHC.Driver.Plugins import Control.Monad import Control.Exception import Data.IORef +import Data.Map ( toList ) import System.FilePath import System.Directory @@ -1159,6 +1161,7 @@ pprModIface iface at ModIface{ mi_final_exts = exts } , text "module header:" $$ nest 2 (ppr (mi_doc_hdr iface)) , text "declaration docs:" $$ nest 2 (ppr (mi_decl_docs iface)) , text "arg docs:" $$ nest 2 (ppr (mi_arg_docs iface)) + , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where pp_hsc_src HsBootFile = text "[boot]" @@ -1248,6 +1251,11 @@ pprIfaceAnnotation :: IfaceAnnotation -> SDoc pprIfaceAnnotation (IfaceAnnotation { ifAnnotatedTarget = target, ifAnnotatedValue = serialized }) = ppr target <+> text "annotated by" <+> ppr serialized +pprExtensibleFields :: ExtensibleFields -> SDoc +pprExtensibleFields (ExtensibleFields fs) = vcat . map pprField $ toList fs + where + pprField (name, (BinData size _data)) = text name <+> text "-" <+> ppr size <+> text "bytes" + {- ********************************************************* * * ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -268,7 +268,8 @@ mkIface_ hsc_env mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields } where cmp_rule = comparing ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/utils/Binary.hs ===================================== @@ -27,6 +27,8 @@ module Binary {-type-} BinHandle, SymbolTable, Dictionary, + BinData(..), dataHandle, handleData, + openBinMem, -- closeBin, @@ -73,6 +75,7 @@ import Fingerprint import GHC.Types.Basic import GHC.Types.SrcLoc +import Control.DeepSeq import Foreign import Data.Array import Data.ByteString (ByteString) @@ -95,6 +98,44 @@ import GHC.Serialized type BinArray = ForeignPtr Word8 + + +--------------------------------------------------------------- +-- BinData +--------------------------------------------------------------- + +data BinData = BinData Int BinArray + +instance NFData BinData where + rnf (BinData sz _) = rnf sz + +instance Binary BinData where + put_ bh (BinData sz dat) = do + put_ bh sz + putPrim bh sz $ \dest -> + withForeignPtr dat $ \orig -> + copyBytes dest orig sz + -- + get bh = do + sz <- get bh + dat <- mallocForeignPtrBytes sz + getPrim bh sz $ \orig -> + withForeignPtr dat $ \dest -> + copyBytes dest orig sz + return (BinData sz dat) + +dataHandle :: BinData -> IO BinHandle +dataHandle (BinData size bin) = do + ixr <- newFastMutInt + szr <- newFastMutInt + writeFastMutInt ixr 0 + writeFastMutInt szr size + binr <- newIORef bin + return (BinMem noUserData ixr szr binr) + +handleData :: BinHandle -> IO BinData +handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -749,6 +749,33 @@ NOT be invoked with your own modules. In the ``ModIface`` datatype you can find lots of useful information, including the exported definitions and type class instances. +The ``ModIface`` datatype also contains facilities for extending it with extra +data, stored in a ``Map`` of serialised fields, indexed by field names and using +GHC's internal ``Binary`` class. The interface to work with these fields is: + +:: + + readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) + writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface + deleteIfaceField :: FieldName -> ModIface -> ModIface + +The ``FieldName`` is open-ended, but typically it should contain the producing +package name, along with the actual field name. Then, the version number can either +be attached to the serialised data for that field, or in cases where multiple versions +of a field could exist in the same interface file, included in the field name. + +Depending on if the field version advances with the package version, or independently, +the version can be attached to either the package name or the field name. Examples of +each case: + +:: + + package/field + ghc-n.n.n/core + package/field-n + +To read an interface file from an external tool without linking to GHC, the format +is described at `Extensible Interface Files`_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ ===================================== testsuite/driver/testlib.py ===================================== @@ -116,6 +116,12 @@ def expect_fail( name, opts ): # future. opts.expect = 'fail'; +def no_lint( name, opts ): + """Disable Core, STG and Cmm lints. Useful when testing compiler perf.""" + opts.compiler_always_flags = \ + [opt for opt in opts.compiler_always_flags \ + if opt not in ['-dcore-lint', '-dstg-lint', '-dcmm-lint']] + def reqlib( lib ): return lambda name, opts, l=lib: _reqlib (name, opts, l ) ===================================== testsuite/tests/ghci/linking/all.T ===================================== @@ -46,7 +46,8 @@ test('T3333', test('T11531', [extra_files(['T11531.hs', 'T11531.c', 'T11531.h']), unless(doing_ghci, skip), - unless(opsys('linux'), skip)], + unless(opsys('linux'), skip), + fragile(11531)], makefile_test, ['T11531']) test('T14708', ===================================== testsuite/tests/hiefile/should_compile/all.T ===================================== @@ -1,6 +1,12 @@ test('hie001', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) -test('hie002', collect_compiler_stats('bytes allocated',10), - compile, ['-fno-code -fwrite-ide-info']) +test('hie002', + [# Allocation numbers unstable on 32-bit, skip: + when(wordsize(32), skip), + # No linting in perf tests: + no_lint, + collect_compiler_stats('bytes allocated',10)], + compile, + ['-fno-code -fwrite-ide-info']) test('hie003', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie004', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie005', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -1,10 +1,5 @@ # Tests that call 'collect_compiler_stats' are skipped when debugging is on. # See testsuite/driver/testlib.py. - -def no_lint(name, opts): - opts.compiler_always_flags = \ - [opt for opt in opts.compiler_always_flags if opt != '-dcore-lint' and opt != '-dcmm-lint'] - setTestOpts(no_lint) test('T1969', ===================================== testsuite/tests/showIface/DocsInHiFile0.stdout ===================================== @@ -2,3 +2,4 @@ module header: Nothing declaration docs: arg docs: +extensible fields: ===================================== testsuite/tests/showIface/DocsInHiFile1.stdout ===================================== @@ -33,4 +33,4 @@ arg docs: p: 0: " An argument" - +extensible fields: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b03ae53c8c455bd665c701fef51bd8813f38e6c9...bcf72afe16c851afae3e0723ea851946750e7b30 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b03ae53c8c455bd665c701fef51bd8813f38e6c9...bcf72afe16c851afae3e0723ea851946750e7b30 You're receiving 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 11 06:33:48 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Sat, 11 Apr 2020 02:33:48 -0400 Subject: [Git][ghc/ghc][wip/T17923] 13 commits: Make NoExtCon fields strict Message-ID: <5e9164cc8fac2_6167136dfb9c440401f@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/T17923 at Glasgow Haskell Compiler / GHC Commits: 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - b287d23e by Simon Peyton Jones at 2020-04-11T09:33:30+03:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 28 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Foreign/Decl.hs - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/PmCheck.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/582ee21f82eadac2d3e92d07f4f0ac4e241e31d3...b287d23e23487f8b2a7214d85916d6d857e31708 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/582ee21f82eadac2d3e92d07f4f0ac4e241e31d3...b287d23e23487f8b2a7214d85916d6d857e31708 You're receiving 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 11 18:33:57 2020 From: gitlab at gitlab.haskell.org (Peter Trommler) Date: Sat, 11 Apr 2020 14:33:57 -0400 Subject: [Git][ghc/ghc][wip/T11261] 20 commits: Don't override proc CafInfos in ticky builds Message-ID: <5e920d95164bc_616776d1c744443530@gitlab.haskell.org.mail> Peter Trommler pushed to branch wip/T11261 at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 374a2ff8 by Peter Trommler at 2020-04-11T14:33:51-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a25735960ea2d8744f6ceb12a03c5aad290aa729...374a2ff8cb2abf076b8eae3ceac96cf4a55f48ac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a25735960ea2d8744f6ceb12a03c5aad290aa729...374a2ff8cb2abf076b8eae3ceac96cf4a55f48ac You're receiving 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 11 19:56:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 15:56:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18043 Message-ID: <5e9220eeb4588_6167134ebbc444501d6@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18043 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18043 You're receiving 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 11 19:58:52 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 15:58:52 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17798 Message-ID: <5e92217c27eb3_616776d1c7444529b6@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T17798 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17798 You're receiving 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 11 20:23:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 16:23:30 -0400 Subject: [Git][ghc/ghc][wip/hadrian-no-export-dynamic-on-darwin] hadrian: Don't --export-dynamic on Darwin Message-ID: <5e922742584d6_6167134ebbc444592bf@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/hadrian-no-export-dynamic-on-darwin at Glasgow Haskell Compiler / GHC Commits: 16700ffb by Ben Gamari at 2020-04-11T16:23:07-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - 2 changed files: - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Packages.hs Changes: ===================================== hadrian/src/Oracles/Setting.hs ===================================== @@ -11,6 +11,7 @@ module Oracles.Setting ( -- ** Target platform things anyTargetPlatform, anyTargetOs, anyTargetArch, anyHostOs, + isElfTarget, ArmVersion(..), targetArmVersion, ghcWithInterpreter, useLibFFIForAdjustors @@ -231,6 +232,13 @@ anyTargetArch = matchSetting TargetArch anyHostOs :: [String] -> Action Bool anyHostOs = matchSetting HostOs +-- | Check whether the target OS uses the ELF object format. +isElfTarget :: Action Bool +isElfTarget = anyTargetOs + [ "linux", "freebsd", "dragonfly", "openbsd", "netbsd", "solaris2", "kfreebsdgnu" + , "haiku", "linux-android" + ] + -- | Check whether the host OS supports the @-rpath@ linker option when -- using dynamic linking. -- ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -127,7 +127,12 @@ packageArgs = do -- refer to the RTS. This is harmless if you don't use it (adds a bit -- of overhead to startup and increases the binary sizes) but if you -- need it there's no alternative. - , package iserv ? mconcat + -- + -- The Solaris linker does not support --export-dynamic option. It also + -- does not need it since it exports all dynamic symbols by default + , package iserv + ? expr isElfTarget + ? notM (expr $ anyTargetOs ["freebsd", "solaris2"])? mconcat [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] -------------------------------- haddock ------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16700ffbf8dd39dfd0ee880ba1c6aff08c051a14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16700ffbf8dd39dfd0ee880ba1c6aff08c051a14 You're receiving 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 11 20:41:59 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 16:41:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/backports Message-ID: <5e922b9763a7f_61673f8199536d9444597da@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/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 Sat Apr 11 20:57:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 16:57:44 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5e922f4884d1e_6167134ebbc444701ae@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: 858adc4c by Ben Gamari at 2020-04-11T16:57:36-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 8 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Trace.c - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,8 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +foreign import ccall "traceFlush" flushEventLog :: IO () ===================================== rts/Capability.c ===================================== @@ -885,6 +885,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/eventlog/EventLog.c ===================================== @@ -271,7 +271,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1565,25 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) { + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = myTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,10 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/858adc4c138e45f6878f22324cf26e07d74e6841 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/858adc4c138e45f6878f22324cf26e07d74e6841 You're receiving 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 11 21:26:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 17:26:33 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5e923609de25b_61677c82e0c44834e4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: 845bcaf5 by Ben Gamari at 2020-04-11T17:26:25-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 9 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,8 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +foreign import ccall "flushTrace" flushEventLog :: IO () ===================================== rts/Capability.c ===================================== @@ -885,6 +885,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushTrace(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/eventlog/EventLog.c ===================================== @@ -271,7 +271,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1565,25 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) { + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = myTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,10 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/845bcaf53a17a011ce6d39a5b06f957034f45fd3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/845bcaf53a17a011ce6d39a5b06f957034f45fd3 You're receiving 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 11 23:54:20 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 19:54:20 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/bump-freebsd-boot Message-ID: <5e9258ac3fc61_6167e4e49b445115b0@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/bump-freebsd-boot at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-freebsd-boot You're receiving 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 12 00:23:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 11 Apr 2020 20:23:46 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5e925f9232948_61673f8199536d944518134@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: 2c9c830d by Ben Gamari at 2020-04-11T20:23:33-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 10 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +flushEventLog :: IO () +flushEventLog = c_flushEventLog nullPtr + +foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO () ===================================== rts/Capability.c ===================================== @@ -885,6 +885,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushTrace(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/Trace.h ===================================== @@ -319,7 +319,6 @@ void traceConcSweepEnd(void); void traceConcUpdRemSetFlush(Capability *cap); void traceNonmovingHeapCensus(uint32_t log_blk_size, const struct NonmovingAllocCensus *census); - void flushTrace(void); #else /* !TRACING */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -16,6 +16,7 @@ #include "RtsUtils.h" #include "Stats.h" #include "EventLog.h" +#include "Schedule.h" #include #include @@ -271,7 +272,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1566,26 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = myTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) @@ -1578,4 +1599,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { void endEventLogging(void) {} +void flushEventLog(Capability **cap STG_UNUSED) {} + #endif /* TRACING */ ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,10 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c9c830d58e41df4e74e1eea936e344805ff88ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c9c830d58e41df4e74e1eea936e344805ff88ad You're receiving 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 12 08:00:18 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 04:00:18 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Testsuite: mark T11531 fragile Message-ID: <5e92ca925b9a9_6167136dfb9c4524940@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - b13435e6 by Simon Peyton Jones at 2020-04-12T03:59:56-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - dea0b597 by Josh Meredith at 2020-04-12T03:59:56-04:00 Implement extensible interface files - - - - - 2afb1a44 by Ryan Scott at 2020-04-12T03:59:57-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 4863c28d by Ben Gamari at 2020-04-12T03:59:57-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - 4e78b765 by Alexis King at 2020-04-12T04:00:10-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 30 changed files: - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/utils/Binary.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/extending_ghc.rst - docs/users_guide/exts/existential_quantification.rst - + docs/users_guide/exts/field_selectors_and_type_applications.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/rank_polymorphism.rst - docs/users_guide/exts/records.rst - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Packages.hs - libraries/base/Control/Category.hs - libraries/base/GHC/Desugar.hs - testsuite/tests/driver/T4437.hs - testsuite/tests/ghci/linking/all.T - + testsuite/tests/indexed-types/should_compile/T17923.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/showIface/DocsInHiFile0.stdout - testsuite/tests/showIface/DocsInHiFile1.stdout - + testsuite/tests/simplCore/should_compile/T18013.hs - + testsuite/tests/simplCore/should_compile/T18013.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ac4eba1ab1c11c0dc079bb1c68e103675cb6c49...4e78b76569e2247cfbe00264990268e6d99b1ab5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ac4eba1ab1c11c0dc079bb1c68e103675cb6c49...4e78b76569e2247cfbe00264990268e6d99b1ab5 You're receiving 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 12 12:45:06 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Sun, 12 Apr 2020 08:45:06 -0400 Subject: [Git][ghc/ghc][wip/lexical-negation] 223 commits: fs: Port fixes from ghc-jailbreak repository Message-ID: <5e930d52e0c13_61677c82e0c454445e@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/lexical-negation at Glasgow Haskell Compiler / GHC Commits: 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - d433ff8b by Vladislav Zavialov at 2020-04-12T15:44:47+03:00 Implement -XLexicalNegation (GHC Proposal #229) This patch introduces a new extension, -XLexicalNegation, which detects whether the minus sign stands for negation or subtraction using the whitespace-based rules described in GHC Proposal #229. - - - - - 30 changed files: - .ghcid - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/linters/check-cpp.py - CODEOWNERS - aclocal.m4 - boot - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f65bac670e865ae489bc7ad7a88fe115ad505880...d433ff8bf82c10da408a70f8945f6c790065a69c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f65bac670e865ae489bc7ad7a88fe115ad505880...d433ff8bf82c10da408a70f8945f6c790065a69c You're receiving 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 12 15:20:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 11:20:26 -0400 Subject: [Git][ghc/ghc][master] testsuite: Fix comment for a language extension Message-ID: <5e9331ba7d82a_616765c7a2845630cc@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - 1 changed file: - testsuite/tests/driver/T4437.hs Changes: ===================================== testsuite/tests/driver/T4437.hs ===================================== @@ -2,7 +2,7 @@ -- sync with Cabal's own extension list. -- -- If you have ended up here due to a test failure, please see --- Note [Adding a language extension] in compiler/main/DynFlags.hs. +-- Note [Adding a language extension] in compiler/GHC/Driver/Session.hs. module Main (main) where @@ -34,7 +34,7 @@ check title expected got showProblems "Unexpected flags" unexpected showProblems "Missing flags" missing --- See Note [Adding a language extension] in compiler/main/DynFlags.hs. +-- See Note [Adding a language extension] in compiler/GHC/Driver/Session.hs. expectedGhcOnlyExtensions :: [String] expectedGhcOnlyExtensions = [ "RelaxedLayout" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0889f5eecfea8af6a9d74d48d9d86ff3aea331d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0889f5eecfea8af6a9d74d48d9d86ff3aea331d6 You're receiving 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 12 15:20:50 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 12 Apr 2020 11:20:50 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5e9331d22c78f_616713503ee045645f7@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: b4430579 by Ben Gamari at 2020-04-12T11:20:40-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 10 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +flushEventLog :: IO () +flushEventLog = c_flushEventLog nullPtr + +foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO () ===================================== rts/Capability.c ===================================== @@ -885,6 +885,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushTrace(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/Trace.h ===================================== @@ -319,7 +319,6 @@ void traceConcSweepEnd(void); void traceConcUpdRemSetFlush(Capability *cap); void traceNonmovingHeapCensus(uint32_t log_blk_size, const struct NonmovingAllocCensus *census); - void flushTrace(void); #else /* !TRACING */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -16,6 +16,7 @@ #include "RtsUtils.h" #include "Stats.h" #include "EventLog.h" +#include "Schedule.h" #include #include @@ -271,7 +272,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1566,26 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = myTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) @@ -1578,4 +1599,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { void endEventLogging(void) {} +void flushEventLog(Capability **cap STG_UNUSED) {} + #endif /* TRACING */ ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,10 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event @@ -175,6 +177,9 @@ void postNonmovingHeapCensus(int log_blk_size, #else /* !TRACING */ +INLINE_HEADER void flushLocalEventsBuf(Capability *cap) +{ /* nothing */ } + INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, EventTypeNum tag STG_UNUSED, StgThreadID id STG_UNUSED, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4430579953571ae4e3655e16cfc6c709893e901 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4430579953571ae4e3655e16cfc6c709893e901 You're receiving 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 12 15:21:12 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 11:21:12 -0400 Subject: [Git][ghc/ghc][master] Significant refactor of Lint Message-ID: <5e9331e867ab9_616776d1c744567998@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 4 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Type.hs - + testsuite/tests/indexed-types/should_compile/T17923.hs - testsuite/tests/indexed-types/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -8,7 +8,7 @@ See Note [Core Lint guarantee]. -} {-# LANGUAGE CPP #-} -{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables, DeriveFunctor #-} module GHC.Core.Lint ( lintCoreBindings, lintUnfolding, @@ -33,7 +33,6 @@ import GHC.Core.Op.Monad import Bag import GHC.Types.Literal import GHC.Core.DataCon -import TysWiredIn import TysPrim import GHC.Tc.Utils.TcType ( isFloatingTy ) import GHC.Types.Var as Var @@ -460,14 +459,17 @@ lintCoreBindings :: DynFlags -> CoreToDo -> [Var] -> CoreProgram -> (Bag MsgDoc, lintCoreBindings dflags pass local_in_scope binds = initL dflags flags local_in_scope $ addLoc TopLevelBindings $ - lintLetBndrs TopLevel binders $ - -- Put all the top-level binders in scope at the start - -- This is because transformation rules can bring something - -- into use 'unexpectedly' do { checkL (null dups) (dupVars dups) ; checkL (null ext_dups) (dupExtVars ext_dups) - ; mapM lint_bind binds } + ; lintRecBindings TopLevel all_pairs $ + return () } where + all_pairs = flattenBinds binds + -- Put all the top-level binders in scope at the start + -- This is because transformation rules can bring something + -- into use 'unexpectedly'; see Note [Glomming] in OccurAnal + binders = map fst all_pairs + flags = defaultLintFlags { lf_check_global_ids = check_globals , lf_check_inline_loop_breakers = check_lbs @@ -493,7 +495,6 @@ lintCoreBindings dflags pass local_in_scope binds CorePrep -> AllowAtTopLevel _ -> AllowAnywhere - binders = bindersOfBinds binds (_, dups) = removeDups compare binders -- dups_ext checks for names with different uniques @@ -508,11 +509,6 @@ lintCoreBindings dflags pass local_in_scope binds = compare (m1, nameOccName n1) (m2, nameOccName n2) | otherwise = LT - -- If you edit this function, you may need to update the GHC formalism - -- See Note [GHC Formalism] - lint_bind (Rec prs) = mapM_ (lintSingleBinding TopLevel Recursive) prs - lint_bind (NonRec bndr rhs) = lintSingleBinding TopLevel NonRecursive (bndr,rhs) - {- ************************************************************************ * * @@ -575,28 +571,32 @@ lintExpr dflags vars expr Check a core binding, returning the list of variables bound. -} -lintSingleBinding :: TopLevelFlag -> RecFlag -> (Id, CoreExpr) -> LintM () --- If you edit this function, you may need to update the GHC formalism --- See Note [GHC Formalism] -lintSingleBinding top_lvl_flag rec_flag (binder,rhs) - = addLoc (RhsOf binder) $ - -- Check the rhs - do { ty <- lintRhs binder rhs - ; binder_ty <- applySubstTy (idType binder) - ; ensureEqTys binder_ty ty (mkRhsMsg binder (text "RHS") ty) +lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)] + -> LintM a -> LintM a +lintRecBindings top_lvl pairs thing_inside + = lintIdBndrs top_lvl bndrs $ \ bndrs' -> + do { zipWithM_ lint_pair bndrs' rhss + ; thing_inside } + where + (bndrs, rhss) = unzip pairs + lint_pair bndr' rhs + = addLoc (RhsOf bndr') $ + do { rhs_ty <- lintRhs bndr' rhs -- Check the rhs + ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty } + +lintLetBind :: TopLevelFlag -> RecFlag -> LintedId + -> CoreExpr -> LintedType -> LintM () +-- Binder's type, and the RHS, have already been linted +-- This function checks other invariants +lintLetBind top_lvl rec_flag binder rhs rhs_ty + = do { let binder_ty = idType binder + ; ensureEqTys binder_ty rhs_ty (mkRhsMsg binder (text "RHS") rhs_ty) -- If the binding is for a CoVar, the RHS should be (Coercion co) -- See Note [Core type and coercion invariant] in GHC.Core ; checkL (not (isCoVar binder) || isCoArg rhs) (mkLetErr binder rhs) - -- Check that it's not levity-polymorphic - -- Do this first, because otherwise isUnliftedType panics - -- Annoyingly, this duplicates the test in lintIdBdr, - -- because for non-rec lets we call lintSingleBinding first - ; checkL (isJoinId binder || not (isTypeLevPoly binder_ty)) - (badBndrTyMsg binder (text "levity-polymorphic")) - -- Check the let/app invariant -- See Note [Core let/app invariant] in GHC.Core ; checkL ( isJoinId binder @@ -609,14 +609,14 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs) -- demanded. Primitive string literals are exempt as there is no -- computation to perform, see Note [Core top-level string literals]. ; checkL (not (isStrictId binder) - || (isNonRec rec_flag && not (isTopLevel top_lvl_flag)) + || (isNonRec rec_flag && not (isTopLevel top_lvl)) || exprIsTickedString rhs) (mkStrictMsg binder) -- Check that if the binder is at the top level and has type Addr#, -- that it is a string literal, see -- Note [Core top-level string literals]. - ; checkL (not (isTopLevel top_lvl_flag && binder_ty `eqType` addrPrimTy) + ; checkL (not (isTopLevel top_lvl && binder_ty `eqType` addrPrimTy) || exprIsTickedString rhs) (mkTopNonLitStrMsg binder) @@ -673,7 +673,9 @@ lintSingleBinding top_lvl_flag rec_flag (binder,rhs) -- join point. -- -- See Note [Checking StaticPtrs]. -lintRhs :: Id -> CoreExpr -> LintM OutType +lintRhs :: Id -> CoreExpr -> LintM LintedType +-- NB: the Id can be Linted or not -- it's only used for +-- its OccInfo and join-pointer-hood lintRhs bndr rhs | Just arity <- isJoinId_maybe bndr = lint_join_lams arity arity True rhs @@ -760,13 +762,14 @@ hurts us here. ************************************************************************ -} --- For OutType, OutKind, the substitution has been applied, --- but has not been linted yet - -type LintedType = Type -- Substitution applied, and type is linted -type LintedKind = Kind +-- Linted things: substitution applied, and type is linted +type LintedType = Type +type LintedKind = Kind +type LintedCoercion = Coercion +type LintedTyCoVar = TyCoVar +type LintedId = Id -lintCoreExpr :: CoreExpr -> LintM OutType +lintCoreExpr :: CoreExpr -> LintM LintedType -- The returned type has the substitution from the monad -- already applied to it: -- lintCoreExpr e subst = exprType (subst e) @@ -775,18 +778,20 @@ lintCoreExpr :: CoreExpr -> LintM OutType -- If you edit this function, you may need to update the GHC formalism -- See Note [GHC Formalism] + lintCoreExpr (Var var) - = lintVarOcc var 0 + = lintIdOcc var 0 lintCoreExpr (Lit lit) = return (literalType lit) lintCoreExpr (Cast expr co) = do { expr_ty <- markAllJoinsBad $ lintCoreExpr expr - ; co' <- applySubstCo co - ; (_, k2, from_ty, to_ty, r) <- lintCoercion co' - ; checkValueKind k2 (text "target of cast" <+> quotes (ppr co)) - ; lintRole co' Representational r + ; co' <- lintCoercion co + ; let (Pair from_ty to_ty, role) = coercionKindRole co' + ; checkValueType to_ty $ + text "target of cast" <+> quotes (ppr co') + ; lintRole co' Representational role ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) ; return to_ty } @@ -808,7 +813,7 @@ lintCoreExpr (Tick tickish expr) lintCoreExpr (Let (NonRec tv (Type ty)) body) | isTyVar tv = -- See Note [Linting type lets] - do { ty' <- applySubstTy ty + do { ty' <- lintType ty ; lintTyBndr tv $ \ tv' -> do { addLoc (RhsOf tv) $ lintTyKind tv' ty' -- Now extend the substitution so we @@ -819,33 +824,34 @@ lintCoreExpr (Let (NonRec tv (Type ty)) body) lintCoreExpr (Let (NonRec bndr rhs) body) | isId bndr - = do { lintSingleBinding NotTopLevel NonRecursive (bndr,rhs) - ; addLoc (BodyOfLetRec [bndr]) - (lintBinder LetBind bndr $ \_ -> - addGoodJoins [bndr] $ - lintCoreExpr body) } + = do { -- First Lint the RHS, before bringing the binder into scope + rhs_ty <- lintRhs bndr rhs + + -- Now lint the binder + ; lintBinder LetBind bndr $ \bndr' -> + do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty + ; addLoc (BodyOfLetRec [bndr]) (lintCoreExpr body) } } | otherwise = failWithL (mkLetErr bndr rhs) -- Not quite accurate lintCoreExpr e@(Let (Rec pairs) body) - = lintLetBndrs NotTopLevel bndrs $ - addGoodJoins bndrs $ - do { -- Check that the list of pairs is non-empty + = do { -- Check that the list of pairs is non-empty checkL (not (null pairs)) (emptyRec e) -- Check that there are no duplicated binders + ; let (_, dups) = removeDups compare bndrs ; checkL (null dups) (dupVars dups) -- Check that either all the binders are joins, or none ; checkL (all isJoinId bndrs || all (not . isJoinId) bndrs) $ - mkInconsistentRecMsg bndrs + mkInconsistentRecMsg bndrs - ; mapM_ (lintSingleBinding NotTopLevel Recursive) pairs - ; addLoc (BodyOfLetRec bndrs) (lintCoreExpr body) } + ; lintRecBindings NotTopLevel pairs $ + addLoc (BodyOfLetRec bndrs) $ + lintCoreExpr body } where bndrs = map fst pairs - (_, dups) = removeDups compare bndrs lintCoreExpr e@(App _ _) = do { fun_ty <- lintCoreFun fun (length args) @@ -866,23 +872,35 @@ lintCoreExpr (Type ty) = failWithL (text "Type found as expression" <+> ppr ty) lintCoreExpr (Coercion co) - = do { (k1, k2, ty1, ty2, role) <- lintInCo co - ; return (mkHeteroCoercionType role k1 k2 ty1 ty2) } + = do { co' <- addLoc (InCo co) $ + lintCoercion co + ; return (coercionType co') } ---------------------- -lintVarOcc :: Var -> Int -- Number of arguments (type or value) being passed - -> LintM Type -- returns type of the *variable* -lintVarOcc var nargs - = do { checkL (isNonCoVarId var) +lintIdOcc :: Var -> Int -- Number of arguments (type or value) being passed + -> LintM LintedType -- returns type of the *variable* +lintIdOcc var nargs + = addLoc (OccOf var) $ + do { checkL (isNonCoVarId var) (text "Non term variable" <+> ppr var) -- See GHC.Core Note [Variable occurrences in Core] -- Check that the type of the occurrence is the same - -- as the type of the binding site - ; ty <- applySubstTy (idType var) - ; var' <- lookupIdInScope var - ; let ty' = idType var' - ; ensureEqTys ty ty' $ mkBndrOccTypeMismatchMsg var' var ty' ty + -- as the type of the binding site. The inScopeIds are + -- /un-substituted/, so this checks that the occurrence type + -- is identical to the binder type. + -- This makes things much easier for things like: + -- /\a. \(x::Maybe a). /\a. ...(x::Maybe a)... + -- The "::Maybe a" on the occurrence is referring to the /outer/ a. + -- If we compared /substituted/ types we'd risk comparing + -- (Maybe a) from the binding site with bogus (Maybe a1) from + -- the occurrence site. Comparing un-substituted types finesses + -- this altogether + ; (bndr, linted_bndr_ty) <- lookupIdInScope var + ; let occ_ty = idType var + bndr_ty = idType bndr + ; ensureEqTys occ_ty bndr_ty $ + mkBndrOccTypeMismatchMsg bndr var bndr_ty occ_ty -- Check for a nested occurrence of the StaticPtr constructor. -- See Note [Checking StaticPtrs]. @@ -894,13 +912,13 @@ lintVarOcc var nargs ; checkDeadIdOcc var ; checkJoinOcc var nargs - ; return (idType var') } + ; return linted_bndr_ty } lintCoreFun :: CoreExpr - -> Int -- Number of arguments (type or val) being passed - -> LintM Type -- Returns type of the *function* + -> Int -- Number of arguments (type or val) being passed + -> LintM LintedType -- Returns type of the *function* lintCoreFun (Var var) nargs - = lintVarOcc var nargs + = lintIdOcc var nargs lintCoreFun (Lam var body) nargs -- Act like lintCoreExpr of Lam, but *don't* call markAllJoinsBad; see @@ -940,7 +958,9 @@ checkJoinOcc var n_args = do { mb_join_arity_bndr <- lookupJoinId var ; case mb_join_arity_bndr of { Nothing -> -- Binder is not a join point - addErrL (invalidJoinOcc var) ; + do { join_set <- getValidJoins + ; addErrL (text "join set " <+> ppr join_set $$ + invalidJoinOcc var) } ; Just join_arity_bndr -> @@ -1037,15 +1057,15 @@ subtype of the required type, as one would expect. -} -lintCoreArgs :: OutType -> [CoreArg] -> LintM OutType +lintCoreArgs :: LintedType -> [CoreArg] -> LintM LintedType lintCoreArgs fun_ty args = foldM lintCoreArg fun_ty args -lintCoreArg :: OutType -> CoreArg -> LintM OutType +lintCoreArg :: LintedType -> CoreArg -> LintM LintedType lintCoreArg fun_ty (Type arg_ty) = do { checkL (not (isCoercionTy arg_ty)) (text "Unnecessary coercion-to-type injection:" <+> ppr arg_ty) - ; arg_ty' <- applySubstTy arg_ty + ; arg_ty' <- lintType arg_ty ; lintTyApp fun_ty arg_ty' } lintCoreArg fun_ty arg @@ -1059,11 +1079,12 @@ lintCoreArg fun_ty arg ; checkL (not (isUnliftedType arg_ty) || exprOkForSpeculation arg) (mkLetAppMsg arg) + ; lintValApp arg fun_ty arg_ty } ----------------- -lintAltBinders :: OutType -- Scrutinee type - -> OutType -- Constructor type +lintAltBinders :: LintedType -- Scrutinee type + -> LintedType -- Constructor type -> [OutVar] -- Binders -> LintM () -- If you edit this function, you may need to update the GHC formalism @@ -1079,7 +1100,7 @@ lintAltBinders scrut_ty con_ty (bndr:bndrs) ; lintAltBinders scrut_ty con_ty' bndrs } ----------------- -lintTyApp :: OutType -> OutType -> LintM OutType +lintTyApp :: LintedType -> LintedType -> LintM LintedType lintTyApp fun_ty arg_ty | Just (tv,body_ty) <- splitForAllTy_maybe fun_ty = do { lintTyKind tv arg_ty @@ -1093,7 +1114,7 @@ lintTyApp fun_ty arg_ty = failWithL (mkTyAppMsg fun_ty arg_ty) ----------------- -lintValApp :: CoreExpr -> OutType -> OutType -> LintM OutType +lintValApp :: CoreExpr -> LintedType -> LintedType -> LintM LintedType lintValApp arg fun_ty arg_ty | Just (arg,res) <- splitFunTy_maybe fun_ty = do { ensureEqTys arg arg_ty err1 @@ -1104,17 +1125,17 @@ lintValApp arg fun_ty arg_ty err1 = mkAppMsg fun_ty arg_ty arg err2 = mkNonFunAppMsg fun_ty arg_ty arg -lintTyKind :: OutTyVar -> OutType -> LintM () +lintTyKind :: OutTyVar -> LintedType -> LintM () -- Both args have had substitution applied -- If you edit this function, you may need to update the GHC formalism -- See Note [GHC Formalism] lintTyKind tyvar arg_ty - = do { arg_kind <- lintType arg_ty - ; unless (arg_kind `eqType` tyvar_kind) - (addErrL (mkKindErrMsg tyvar arg_ty $$ (text "Linted Arg kind:" <+> ppr arg_kind))) } + = unless (arg_kind `eqType` tyvar_kind) $ + addErrL (mkKindErrMsg tyvar arg_ty $$ (text "Linted Arg kind:" <+> ppr arg_kind)) where tyvar_kind = tyVarKind tyvar + arg_kind = typeKind arg_ty {- ************************************************************************ @@ -1124,7 +1145,7 @@ lintTyKind tyvar arg_ty ************************************************************************ -} -lintCaseExpr :: CoreExpr -> Id -> Type -> [CoreAlt] -> LintM OutType +lintCaseExpr :: CoreExpr -> Id -> Type -> [CoreAlt] -> LintM LintedType lintCaseExpr scrut var alt_ty alts = do { let e = Case scrut var alt_ty alts -- Just for error messages @@ -1133,10 +1154,10 @@ lintCaseExpr scrut var alt_ty alts = -- See Note [Join points are less general than the paper] -- in GHC.Core - ; (alt_ty, _) <- addLoc (CaseTy scrut) $ - lintInTy alt_ty - ; (var_ty, _) <- addLoc (IdTy var) $ - lintInTy (idType var) + ; alt_ty <- addLoc (CaseTy scrut) $ + lintValueType alt_ty + ; var_ty <- addLoc (IdTy var) $ + lintValueType (idType var) -- We used to try to check whether a case expression with no -- alternatives was legitimate, but this didn't work. @@ -1178,7 +1199,7 @@ lintCaseExpr scrut var alt_ty alts = ; checkCaseAlts e scrut_ty alts ; return alt_ty } } -checkCaseAlts :: CoreExpr -> OutType -> [CoreAlt] -> LintM () +checkCaseAlts :: CoreExpr -> LintedType -> [CoreAlt] -> LintM () -- a) Check that the alts are non-empty -- b1) Check that the DEFAULT comes first, if it exists -- b2) Check that the others are in increasing order @@ -1218,14 +1239,14 @@ checkCaseAlts e ty alts = Nothing -> False Just tycon -> isPrimTyCon tycon -lintAltExpr :: CoreExpr -> OutType -> LintM () +lintAltExpr :: CoreExpr -> LintedType -> LintM () lintAltExpr expr ann_ty = do { actual_ty <- lintCoreExpr expr ; ensureEqTys actual_ty ann_ty (mkCaseAltMsg expr actual_ty ann_ty) } -- See GHC.Core Note [Case expression invariants] item (6) -lintCoreAlt :: OutType -- Type of scrutinee - -> OutType -- Type of the alternative +lintCoreAlt :: LintedType -- Type of scrutinee + -> LintedType -- Type of the alternative -> CoreAlt -> LintM () -- If you edit this function, you may need to update the GHC formalism @@ -1285,40 +1306,43 @@ lintBinders site (var:vars) linterF = lintBinder site var $ \var' -> -- See Note [GHC Formalism] lintBinder :: BindingSite -> Var -> (Var -> LintM a) -> LintM a lintBinder site var linterF - | isTyVar var = lintTyBndr var linterF - | isCoVar var = lintCoBndr var linterF - | otherwise = lintIdBndr NotTopLevel site var linterF + | isTyCoVar var = lintTyCoBndr var linterF + | otherwise = lintIdBndr NotTopLevel site var linterF -lintTyBndr :: InTyVar -> (OutTyVar -> LintM a) -> LintM a -lintTyBndr tv thing_inside - = do { subst <- getTCvSubst - ; let (subst', tv') = substTyVarBndr subst tv - ; lintKind (varType tv') - ; updateTCvSubst subst' (thing_inside tv') } +lintTyBndr :: TyVar -> (LintedTyCoVar -> LintM a) -> LintM a +lintTyBndr = lintTyCoBndr -- We could specialise it, I guess + +-- lintCoBndr :: CoVar -> (LintedTyCoVar -> LintM a) -> LintM a +-- lintCoBndr = lintTyCoBndr -- We could specialise it, I guess -lintCoBndr :: InCoVar -> (OutCoVar -> LintM a) -> LintM a -lintCoBndr cv thing_inside +lintTyCoBndr :: TyCoVar -> (LintedTyCoVar -> LintM a) -> LintM a +lintTyCoBndr tcv thing_inside = do { subst <- getTCvSubst - ; let (subst', cv') = substCoVarBndr subst cv - ; lintKind (varType cv') - ; lintL (isCoVarType (varType cv')) - (text "CoVar with non-coercion type:" <+> pprTyVar cv) - ; updateTCvSubst subst' (thing_inside cv') } - -lintLetBndrs :: TopLevelFlag -> [Var] -> LintM a -> LintM a -lintLetBndrs top_lvl ids linterF - = go ids + ; kind' <- lintType (varType tcv) + ; let tcv' = uniqAway (getTCvInScope subst) $ + setVarType tcv kind' + subst' = extendTCvSubstWithClone subst tcv tcv' + ; when (isCoVar tcv) $ + lintL (isCoVarType kind') + (text "CoVar with non-coercion type:" <+> pprTyVar tcv) + ; updateTCvSubst subst' (thing_inside tcv') } + +lintIdBndrs :: forall a. TopLevelFlag -> [Id] -> ([LintedId] -> LintM a) -> LintM a +lintIdBndrs top_lvl ids thing_inside + = go ids thing_inside where - go [] = linterF - go (id:ids) = lintIdBndr top_lvl LetBind id $ \_ -> - go ids + go :: [Id] -> ([Id] -> LintM a) -> LintM a + go [] thing_inside = thing_inside [] + go (id:ids) thing_inside = lintIdBndr top_lvl LetBind id $ \id' -> + go ids $ \ids' -> + thing_inside (id' : ids') lintIdBndr :: TopLevelFlag -> BindingSite -> InVar -> (OutVar -> LintM a) -> LintM a -- Do substitution on the type of a binder and add the var with this -- new type to the in-scope set of the second argument -- ToDo: lint its rules -lintIdBndr top_lvl bind_site id linterF +lintIdBndr top_lvl bind_site id thing_inside = ASSERT2( isId id, ppr id ) do { flags <- getLintFlags ; checkL (not (lf_check_global_ids flags) || isLocalId id) @@ -1333,14 +1357,11 @@ lintIdBndr top_lvl bind_site id linterF ; checkL (not (isExternalName (Var.varName id)) || is_top_lvl) (mkNonTopExternalNameMsg id) - ; (id_ty, k) <- addLoc (IdTy id) $ - lintInTy (idType id) - ; let id' = setIdType id id_ty - -- See Note [Levity polymorphism invariants] in GHC.Core - ; lintL (isJoinId id || not (lf_check_levity_poly flags) || not (isKindLevPoly k)) - (text "Levity-polymorphic binder:" <+> - (ppr id <+> dcolon <+> parens (ppr id_ty <+> dcolon <+> ppr k))) + ; lintL (isJoinId id || not (lf_check_levity_poly flags) + || not (isTypeLevPoly id_ty)) $ + text "Levity-polymorphic binder:" <+> ppr id <+> dcolon <+> + parens (ppr id_ty <+> dcolon <+> ppr (typeKind id_ty)) -- Check that a join-id is a not-top-level let-binding ; when (isJoinId id) $ @@ -1352,8 +1373,13 @@ lintIdBndr top_lvl bind_site id linterF ; lintL (not (isCoVarType id_ty)) (text "Non-CoVar has coercion type" <+> ppr id <+> dcolon <+> ppr id_ty) - ; addInScopeId id' $ (linterF id') } + ; linted_ty <- addLoc (IdTy id) (lintValueType id_ty) + + ; addInScopeId id linted_ty $ + thing_inside (setIdType id linted_ty) } where + id_ty = idType id + is_top_lvl = isTopLevel top_lvl is_let_bind = case bind_site of LetBind -> True @@ -1377,45 +1403,58 @@ lintTypes dflags vars tys where (_warns, errs) = initL dflags defaultLintFlags vars linter linter = lintBinders LambdaBind vars $ \_ -> - mapM_ lintInTy tys + mapM_ lintType tys -lintInTy :: InType -> LintM (LintedType, LintedKind) +lintValueType :: Type -> LintM LintedType -- Types only, not kinds -- Check the type, and apply the substitution to it -- See Note [Linting type lets] -lintInTy ty +lintValueType ty = addLoc (InType ty) $ - do { ty' <- applySubstTy ty - ; k <- lintType ty' - ; addLoc (InKind ty' k) $ - lintKind k -- The kind returned by lintType is already - -- a LintedKind but we also want to check that - -- k :: *, which lintKind does - ; return (ty', k) } + do { ty' <- lintType ty + ; let sk = typeKind ty' + ; lintL (classifiesTypeWithValues sk) $ + hang (text "Ill-kinded type:" <+> ppr ty) + 2 (text "has kind:" <+> ppr sk) + ; return ty' } checkTyCon :: TyCon -> LintM () checkTyCon tc = checkL (not (isTcTyCon tc)) (text "Found TcTyCon:" <+> ppr tc) ------------------- -lintType :: OutType -> LintM LintedKind --- The returned Kind has itself been linted +lintType :: LintedType -> LintM LintedType -- If you edit this function, you may need to update the GHC formalism -- See Note [GHC Formalism] lintType (TyVarTy tv) - = do { checkL (isTyVar tv) (mkBadTyVarMsg tv) - ; tv' <- lintTyCoVarInScope tv - ; return (tyVarKind tv') } - -- We checked its kind when we added it to the envt + | not (isTyVar tv) + = failWithL (mkBadTyVarMsg tv) + + | otherwise + = do { subst <- getTCvSubst + ; case lookupTyVar subst tv of + Just linted_ty -> return linted_ty + + -- 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") + } lintType ty@(AppTy t1 t2) | TyConApp {} <- t1 = failWithL $ text "TyConApp to the left of AppTy:" <+> ppr ty | otherwise - = do { k1 <- lintType t1 - ; k2 <- lintType t2 - ; lint_ty_app ty k1 [(t2,k2)] } + = do { t1' <- lintType t1 + ; t2' <- lintType t2 + ; lint_ty_app ty (typeKind t1') [t2'] + ; return (AppTy t1' t2') } lintType ty@(TyConApp tc tys) | isTypeSynonymTyCon tc || isTypeFamilyTyCon tc @@ -1432,71 +1471,72 @@ lintType ty@(TyConApp tc tys) | otherwise -- Data types, data families, primitive types = do { checkTyCon tc - ; ks <- mapM lintType tys - ; lint_ty_app ty (tyConKind tc) (tys `zip` ks) } + ; tys' <- mapM lintType tys + ; lint_ty_app ty (tyConKind tc) tys' + ; return (TyConApp tc tys') } -- arrows can related *unlifted* kinds, so this has to be separate from -- a dependent forall. -lintType ty@(FunTy _ t1 t2) - = do { k1 <- lintType t1 - ; k2 <- lintType t2 - ; lintArrow (text "type or kind" <+> quotes (ppr ty)) k1 k2 } +lintType ty@(FunTy af t1 t2) + = do { t1' <- lintType t1 + ; t2' <- lintType t2 + ; lintArrow (text "type or kind" <+> quotes (ppr ty)) t1' t2' + ; return (FunTy af t1' t2') } + +lintType ty@(ForAllTy (Bndr tcv vis) body_ty) + | not (isTyCoVar tcv) + = failWithL (text "Non-Tyvar or Non-Covar bound in type:" <+> ppr ty) + | otherwise + = lintTyCoBndr tcv $ \tcv' -> + do { body_ty' <- lintType body_ty + ; lintForAllBody tcv' body_ty' -lintType t@(ForAllTy (Bndr tv _vis) ty) - -- forall over types - | isTyVar tv - = lintTyBndr tv $ \tv' -> - do { k <- lintType ty - ; checkValueKind k (text "the body of forall:" <+> ppr t) - ; case occCheckExpand [tv'] k of -- See Note [Stupid type synonyms] - Just k' -> return k' - Nothing -> failWithL (hang (text "Variable escape in forall:") - 2 (vcat [ text "type:" <+> ppr t - , text "kind:" <+> ppr k ])) - } + ; when (isCoVar tcv) $ + lintL (tcv `elemVarSet` tyCoVarsOfType body_ty) $ + text "Covar does not occur in the body:" <+> (ppr tcv $$ ppr body_ty) + -- See GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy] + -- and cf GHC.Core.Coercion Note [Unused coercion variable in ForAllCo] + + ; return (ForAllTy (Bndr tcv' vis) body_ty') } -lintType t@(ForAllTy (Bndr cv _vis) ty) - -- forall over coercions - = do { lintL (isCoVar cv) - (text "Non-Tyvar or Non-Covar bound in type:" <+> ppr t) - ; lintL (cv `elemVarSet` tyCoVarsOfType ty) - (text "Covar does not occur in the body:" <+> ppr t) - ; lintCoBndr cv $ \_ -> - do { k <- lintType ty - ; checkValueKind k (text "the body of forall:" <+> ppr t) - ; return liftedTypeKind - -- We don't check variable escape here. Namely, k could refer to cv' - }} - -lintType ty@(LitTy l) = lintTyLit l >> return (typeKind ty) +lintType ty@(LitTy l) + = do { lintTyLit l; return ty } lintType (CastTy ty co) - = do { k1 <- lintType ty - ; (k1', k2) <- lintStarCoercion co - ; ensureEqTys k1 k1' (mkCastTyErr ty co k1' k1) - ; return k2 } + = do { ty' <- lintType ty + ; co' <- lintStarCoercion co + ; let tyk = typeKind ty' + cok = coercionLKind co' + ; ensureEqTys tyk cok (mkCastTyErr ty co tyk cok) + ; return (CastTy ty' co') } lintType (CoercionTy co) - = do { (k1, k2, ty1, ty2, r) <- lintCoercion co - ; return $ mkHeteroCoercionType r k1 k2 ty1 ty2 } - -{- Note [Stupid type synonyms] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider (#14939) - type Alg cls ob = ob - f :: forall (cls :: * -> Constraint) (b :: Alg cls *). b - -Here 'cls' appears free in b's kind, which would usually be illegal -(because in (forall a. ty), ty's kind should not mention 'a'). But -#in this case (Alg cls *) = *, so all is well. Currently we allow -this, and make Lint expand synonyms where necessary to make it so. - -c.f. GHC.Tc.Utils.Unify.occCheckExpand and GHC.Core.Utils.coreAltsType which deal -with the same problem. A single systematic solution eludes me. --} + = do { co' <- lintCoercion co + ; return (CoercionTy co') } + +----------------- +lintForAllBody :: LintedTyCoVar -> LintedType -> LintM () +-- Do the checks for the body of a forall-type +lintForAllBody tcv body_ty + = do { checkValueType body_ty (text "the body of forall:" <+> ppr body_ty) + + -- For type variables, check for skolem escape + -- See Note [Phantom type variables in kinds] in GHC.Core.Type + -- The kind of (forall cv. th) is liftedTypeKind, so no + -- need to check for skolem-escape in the CoVar case + ; let body_kind = typeKind body_ty + ; when (isTyVar tcv) $ + case occCheckExpand [tcv] body_kind of + Just {} -> return () + Nothing -> failWithL $ + hang (text "Variable escape in forall:") + 2 (vcat [ text "tyvar:" <+> ppr tcv + , text "type:" <+> ppr body_ty + , text "kind:" <+> ppr body_kind ]) + } ----------------- -lintTySynFamApp :: Bool -> Type -> TyCon -> [Type] -> LintM LintedKind +lintTySynFamApp :: Bool -> InType -> TyCon -> [InType] -> LintM LintedType -- The TyCon is a type synonym or a type family (not a data family) -- See Note [Linting type synonym applications] -- c.f. GHC.Tc.Validity.check_syn_tc_app @@ -1510,58 +1550,54 @@ lintTySynFamApp report_unsat ty tc tys , let expanded_ty = mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys' = do { -- Kind-check the argument types, but without reporting -- un-saturated type families/synonyms - ks <- setReportUnsat False (mapM lintType tys) + tys' <- setReportUnsat False (mapM lintType tys) ; when report_unsat $ do { _ <- lintType expanded_ty ; return () } - ; lint_ty_app ty (tyConKind tc) (tys `zip` ks) } + ; lint_ty_app ty (tyConKind tc) tys' + ; return (TyConApp tc tys') } -- Otherwise this must be a type family | otherwise - = do { ks <- mapM lintType tys - ; lint_ty_app ty (tyConKind tc) (tys `zip` ks) } - ------------------ -lintKind :: OutKind -> LintM () --- If you edit this function, you may need to update the GHC formalism --- See Note [GHC Formalism] -lintKind k = do { sk <- lintType k - ; unless (classifiesTypeWithValues sk) - (addErrL (hang (text "Ill-kinded kind:" <+> ppr k) - 2 (text "has kind:" <+> ppr sk))) } + = do { tys' <- mapM lintType tys + ; lint_ty_app ty (tyConKind tc) tys' + ; return (TyConApp tc tys') } ----------------- -- Confirms that a type is really *, #, Constraint etc -checkValueKind :: OutKind -> SDoc -> LintM () -checkValueKind k doc - = lintL (classifiesTypeWithValues k) - (text "Non-*-like kind when *-like expected:" <+> ppr k $$ +checkValueType :: LintedType -> SDoc -> LintM () +checkValueType ty doc + = lintL (classifiesTypeWithValues kind) + (text "Non-*-like kind when *-like expected:" <+> ppr kind $$ text "when checking" <+> doc) + where + kind = typeKind ty ----------------- -lintArrow :: SDoc -> LintedKind -> LintedKind -> LintM LintedKind +lintArrow :: SDoc -> LintedType -> LintedType -> LintM () -- If you edit this function, you may need to update the GHC formalism -- See Note [GHC Formalism] -lintArrow what k1 k2 -- Eg lintArrow "type or kind `blah'" k1 k2 +lintArrow what t1 t2 -- Eg lintArrow "type or kind `blah'" k1 k2 -- or lintArrow "coercion `blah'" k1 k2 = do { unless (classifiesTypeWithValues k1) (addErrL (msg (text "argument") k1)) - ; unless (classifiesTypeWithValues k2) (addErrL (msg (text "result") k2)) - ; return liftedTypeKind } + ; unless (classifiesTypeWithValues k2) (addErrL (msg (text "result") k2)) } where + k1 = typeKind t1 + k2 = typeKind t2 msg ar k = vcat [ hang (text "Ill-kinded" <+> ar) 2 (text "in" <+> what) , what <+> text "kind:" <+> ppr k ] ----------------- -lint_ty_app :: Type -> LintedKind -> [(LintedType,LintedKind)] -> LintM LintedKind +lint_ty_app :: Type -> LintedKind -> [LintedType] -> LintM () lint_ty_app ty k tys = lint_app (text "type" <+> quotes (ppr ty)) k tys ---------------- -lint_co_app :: Coercion -> LintedKind -> [(LintedType,LintedKind)] -> LintM LintedKind +lint_co_app :: Coercion -> LintedKind -> [LintedType] -> LintM () lint_co_app ty k tys = lint_app (text "coercion" <+> quotes (ppr ty)) k tys @@ -1573,42 +1609,45 @@ lintTyLit (NumTyLit n) where msg = text "Negative type literal:" <+> integer n lintTyLit (StrTyLit _) = return () -lint_app :: SDoc -> LintedKind -> [(LintedType,LintedKind)] -> LintM Kind +lint_app :: SDoc -> LintedKind -> [LintedType] -> LintM () -- (lint_app d fun_kind arg_tys) -- We have an application (f arg_ty1 .. arg_tyn), -- where f :: fun_kind --- Takes care of linting the OutTypes -- If you edit this function, you may need to update the GHC formalism -- See Note [GHC Formalism] -lint_app doc kfn kas +lint_app doc kfn arg_tys = do { in_scope <- getInScope -- We need the in_scope set to satisfy the invariant in -- Note [The substitution invariant] in GHC.Core.TyCo.Subst - ; foldlM (go_app in_scope) kfn kas } + ; _ <- foldlM (go_app in_scope) kfn arg_tys + ; return () } where fail_msg extra = vcat [ hang (text "Kind application error in") 2 doc , nest 2 (text "Function kind =" <+> ppr kfn) - , nest 2 (text "Arg kinds =" <+> ppr kas) + , nest 2 (text "Arg types =" <+> ppr arg_tys) , extra ] - go_app in_scope kfn tka + go_app in_scope kfn ta | Just kfn' <- coreView kfn - = go_app in_scope kfn' tka + = go_app in_scope kfn' ta - go_app _ (FunTy _ kfa kfb) tka@(_,ka) - = do { unless (ka `eqType` kfa) $ - addErrL (fail_msg (text "Fun:" <+> (ppr kfa $$ ppr tka))) + go_app _ fun_kind@(FunTy _ kfa kfb) ta + = do { let ka = typeKind ta + ; unless (ka `eqType` kfa) $ + addErrL (fail_msg (text "Fun:" <+> (ppr fun_kind $$ ppr ta <+> dcolon <+> ppr ka))) ; return kfb } - go_app in_scope (ForAllTy (Bndr kv _vis) kfn) tka@(ta,ka) + go_app in_scope (ForAllTy (Bndr kv _vis) kfn) ta = do { let kv_kind = varType kv + ka = typeKind ta ; unless (ka `eqType` kv_kind) $ - addErrL (fail_msg (text "Forall:" <+> (ppr kv $$ ppr kv_kind $$ ppr tka))) + addErrL (fail_msg (text "Forall:" <+> (ppr kv $$ ppr kv_kind $$ + ppr ta <+> dcolon <+> ppr ka))) ; return $ substTy (extendTCvSubst (mkEmptyTCvSubst in_scope) kv ta) kfn } - go_app _ kfn ka - = failWithL (fail_msg (text "Not a fun:" <+> (ppr kfn $$ ppr ka))) + go_app _ kfn ta + = failWithL (fail_msg (text "Not a fun:" <+> (ppr kfn $$ ppr ta))) {- ********************************************************************* * * @@ -1616,7 +1655,7 @@ lint_app doc kfn kas * * ********************************************************************* -} -lintCoreRule :: OutVar -> OutType -> CoreRule -> LintM () +lintCoreRule :: OutVar -> LintedType -> CoreRule -> LintM () lintCoreRule _ _ (BuiltinRule {}) = return () -- Don't bother @@ -1709,68 +1748,94 @@ Note [Rules and join points] in OccurAnal for further discussion. ************************************************************************ -} -lintInCo :: InCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) --- Check the coercion, and apply the substitution to it --- See Note [Linting type lets] -lintInCo co - = addLoc (InCo co) $ - do { co' <- applySubstCo co - ; lintCoercion co' } +{- Note [Asymptotic efficiency] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When linting coercions (and types actually) we return a linted +(substituted) coercion. Then we often have to take the coercionKind of +that returned coercion. If we get long chains, that can be asymptotically +inefficient, notably in +* TransCo +* InstCo +* NthCo (cf #9233) +* LRCo + +But the code is simple. And this is only Lint. Let's wait to see if +the bad perf bites us in practice. + +A solution would be to return the kind and role of the coercion, +as well as the linted coercion. Or perhaps even *only* the kind and role, +which is what used to happen. But that proved tricky and error prone +(#17923), so now we return the coercion. +-} + -- lints a coercion, confirming that its lh kind and its rh kind are both * -- also ensures that the role is Nominal -lintStarCoercion :: OutCoercion -> LintM (LintedType, LintedType) +lintStarCoercion :: InCoercion -> LintM LintedCoercion lintStarCoercion g - = do { (k1, k2, t1, t2, r) <- lintCoercion g - ; checkValueKind k1 (text "the kind of the left type in" <+> ppr g) - ; checkValueKind k2 (text "the kind of the right type in" <+> ppr g) - ; lintRole g Nominal r - ; return (t1, t2) } - -lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) --- Check the kind of a coercion term, returning the kind --- Post-condition: the returned OutTypes are lint-free --- --- If lintCoercion co = (k1, k2, s1, s2, r) --- then co :: s1 ~r s2 --- s1 :: k1 --- s2 :: k2 - + = do { g' <- lintCoercion g + ; let Pair t1 t2 = coercionKind g' + ; checkValueType t1 (text "the kind of the left type in" <+> ppr g) + ; checkValueType t2 (text "the kind of the right type in" <+> ppr g) + ; lintRole g Nominal (coercionRole g) + ; return g' } + +lintCoercion :: InCoercion -> LintM LintedCoercion -- If you edit this function, you may need to update the GHC formalism -- See Note [GHC Formalism] + +lintCoercion (CoVarCo cv) + | not (isCoVar cv) + = failWithL (hang (text "Bad CoVarCo:" <+> ppr cv) + 2 (text "With offending type:" <+> ppr (varType cv))) + + | otherwise + = do { subst <- getTCvSubst + ; case lookupCoVar subst cv of + Just linted_co -> return linted_co ; + Nothing -> -- lintCoBndr always extends the substitition + failWithL $ + hang (text "The coercion variable" <+> pprBndr LetBind cv) + 2 (text "is out of scope") + } + + lintCoercion (Refl ty) - = do { k <- lintType ty - ; return (k, k, ty, ty, Nominal) } + = do { ty' <- lintType ty + ; return (Refl ty') } lintCoercion (GRefl r ty MRefl) - = do { k <- lintType ty - ; return (k, k, ty, ty, r) } + = do { ty' <- lintType ty + ; return (GRefl r ty' MRefl) } lintCoercion (GRefl r ty (MCo co)) - = do { k <- lintType ty - ; (_, _, k1, k2, r') <- lintCoercion co - ; ensureEqTys k k1 - (hang (text "GRefl coercion kind mis-match:" <+> ppr co) - 2 (vcat [ppr ty, ppr k, ppr k1])) - ; lintRole co Nominal r' - ; return (k1, k2, ty, mkCastTy ty co, r) } + = do { ty' <- lintType ty + ; co' <- lintCoercion co + ; let tk = typeKind ty' + tl = coercionLKind co' + ; ensureEqTys tk tl $ + hang (text "GRefl coercion kind mis-match:" <+> ppr co) + 2 (vcat [ppr ty', ppr tk, ppr tl]) + ; lintRole co' Nominal (coercionRole co') + ; return (GRefl r ty' (MCo co')) } lintCoercion co@(TyConAppCo r tc cos) | tc `hasKey` funTyConKey , [_rep1,_rep2,_co1,_co2] <- cos - = do { failWithL (text "Saturated TyConAppCo (->):" <+> ppr co) - } -- All saturated TyConAppCos should be FunCos + = failWithL (text "Saturated TyConAppCo (->):" <+> ppr co) + -- All saturated TyConAppCos should be FunCos | Just {} <- synTyConDefn_maybe tc = failWithL (text "Synonym in TyConAppCo:" <+> ppr co) | otherwise = do { checkTyCon tc - ; (k's, ks, ss, ts, rs) <- mapAndUnzip5M lintCoercion cos - ; k' <- lint_co_app co (tyConKind tc) (ss `zip` k's) - ; k <- lint_co_app co (tyConKind tc) (ts `zip` ks) - ; _ <- zipWith3M lintRole cos (tyConRolesX r tc) rs - ; return (k', k, mkTyConApp tc ss, mkTyConApp tc ts, r) } + ; cos' <- mapM lintCoercion cos + ; let (co_kinds, co_roles) = unzip (map coercionKindRole cos') + ; lint_co_app co (tyConKind tc) (map pFst co_kinds) + ; lint_co_app co (tyConKind tc) (map pSnd co_kinds) + ; zipWithM_ (lintRole co) (tyConRolesX r tc) co_roles + ; return (TyConAppCo r tc cos') } lintCoercion co@(AppCo co1 co2) | TyConAppCo {} <- co1 @@ -1778,111 +1843,75 @@ lintCoercion co@(AppCo co1 co2) | Just (TyConApp {}, _) <- isReflCo_maybe co1 = failWithL (text "Refl (TyConApp ...) to the left of AppCo:" <+> ppr co) | otherwise - = do { (k1, k2, s1, s2, r1) <- lintCoercion co1 - ; (k'1, k'2, t1, t2, r2) <- lintCoercion co2 - ; k3 <- lint_co_app co k1 [(t1,k'1)] - ; k4 <- lint_co_app co k2 [(t2,k'2)] + = do { co1' <- lintCoercion co1 + ; co2' <- lintCoercion co2 + ; let (Pair lk1 rk1, r1) = coercionKindRole co1' + (Pair lk2 rk2, r2) = coercionKindRole co2' + ; lint_co_app co (typeKind lk1) [lk2] + ; lint_co_app co (typeKind rk1) [rk2] + ; if r1 == Phantom then lintL (r2 == Phantom || r2 == Nominal) (text "Second argument in AppCo cannot be R:" $$ ppr co) else lintRole co Nominal r2 - ; return (k3, k4, mkAppTy s1 t1, mkAppTy s2 t2, r1) } + + ; return (AppCo co1' co2') } ---------- -lintCoercion (ForAllCo tv1 kind_co co) - -- forall over types - | isTyVar tv1 - = do { (_, k2) <- lintStarCoercion kind_co - ; let tv2 = setTyVarKind tv1 k2 - ; addInScopeTyCoVar tv1 $ - do { - ; (k3, k4, t1, t2, r) <- lintCoercion co - ; in_scope <- getInScope - ; let tyl = mkInvForAllTy tv1 t1 - subst = mkTvSubst in_scope $ - -- We need both the free vars of the `t2` and the - -- free vars of the range of the substitution in - -- scope. All the free vars of `t2` and `kind_co` should - -- already be in `in_scope`, because they've been - -- linted and `tv2` has the same unique as `tv1`. - -- See Note [The substitution invariant] in GHC.Core.TyCo.Subst. - unitVarEnv tv1 (TyVarTy tv2 `mkCastTy` mkSymCo kind_co) - tyr = mkInvForAllTy tv2 $ - substTy subst t2 - ; return (k3, k4, tyl, tyr, r) } } - -lintCoercion (ForAllCo cv1 kind_co co) - -- forall over coercions - = ASSERT( isCoVar cv1 ) - do { lintL (almostDevoidCoVarOfCo cv1 co) - (text "Covar can only appear in Refl and GRefl: " <+> ppr co) - ; (_, k2) <- lintStarCoercion kind_co - ; let cv2 = setVarType cv1 k2 - ; addInScopeTyCoVar cv1 $ - do { - ; (k3, k4, t1, t2, r) <- lintCoercion co - ; checkValueKind k3 (text "the body of a ForAllCo over covar:" <+> ppr co) - ; checkValueKind k4 (text "the body of a ForAllCo over covar:" <+> ppr co) - -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep - ; in_scope <- getInScope - ; let tyl = mkTyCoInvForAllTy cv1 t1 - r2 = coVarRole cv1 - kind_co' = downgradeRole r2 Nominal kind_co - eta1 = mkNthCo r2 2 kind_co' - eta2 = mkNthCo r2 3 kind_co' - subst = mkCvSubst in_scope $ - -- We need both the free vars of the `t2` and the - -- free vars of the range of the substitution in - -- scope. All the free vars of `t2` and `kind_co` should - -- already be in `in_scope`, because they've been - -- linted and `cv2` has the same unique as `cv1`. - -- See Note [The substitution invariant] in GHC.Core.TyCo.Subst. - unitVarEnv cv1 (eta1 `mkTransCo` (mkCoVarCo cv2) - `mkTransCo` (mkSymCo eta2)) - tyr = mkTyCoInvForAllTy cv2 $ - substTy subst t2 - ; return (liftedTypeKind, liftedTypeKind, tyl, tyr, r) } } - -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep +lintCoercion co@(ForAllCo tcv kind_co body_co) + | not (isTyCoVar tcv) + = failWithL (text "Non tyco binder in ForAllCo:" <+> ppr co) + | otherwise + = do { kind_co' <- lintStarCoercion kind_co + ; lintTyCoBndr tcv $ \tcv' -> + do { body_co' <- lintCoercion body_co + ; ensureEqTys (varType tcv') (coercionLKind kind_co') $ + text "Kind mis-match in ForallCo" <+> ppr co + + -- Assuming kind_co :: k1 ~ k2 + -- Need to check that + -- (forall (tcv:k1). lty) and + -- (forall (tcv:k2). rty[(tcv:k2) |> sym kind_co/tcv]) + -- are both well formed. Easiest way is to call lintForAllBody + -- for each; there is actually no need to do the funky substitution + ; let Pair lty rty = coercionKind body_co' + ; lintForAllBody tcv' lty + ; lintForAllBody tcv' rty + + ; when (isCoVar tcv) $ + lintL (almostDevoidCoVarOfCo tcv body_co) $ + text "Covar can only appear in Refl and GRefl: " <+> ppr co + -- See "last wrinkle" in GHC.Core.Coercion + -- Note [Unused coercion variable in ForAllCo] + -- and c.f. GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy] + + ; return (ForAllCo tcv' kind_co' body_co') } } lintCoercion co@(FunCo r co1 co2) - = do { (k1,k'1,s1,t1,r1) <- lintCoercion co1 - ; (k2,k'2,s2,t2,r2) <- lintCoercion co2 - ; k <- lintArrow (text "coercion" <+> quotes (ppr co)) k1 k2 - ; k' <- lintArrow (text "coercion" <+> quotes (ppr co)) k'1 k'2 - ; lintRole co1 r r1 - ; lintRole co2 r r2 - ; return (k, k', mkVisFunTy s1 s2, mkVisFunTy t1 t2, r) } - -lintCoercion (CoVarCo cv) - | not (isCoVar cv) - = failWithL (hang (text "Bad CoVarCo:" <+> ppr cv) - 2 (text "With offending type:" <+> ppr (varType cv))) - | otherwise - = do { cv' <- lintTyCoVarInScope cv - ; lintUnliftedCoVar cv' - ; return $ coVarKindsTypesRole cv' } + = do { co1' <- lintCoercion co1 + ; co2' <- lintCoercion co2 + ; let Pair lt1 rt1 = coercionKind co1 + Pair lt2 rt2 = coercionKind co2 + ; lintArrow (text "coercion" <+> quotes (ppr co)) lt1 lt2 + ; lintArrow (text "coercion" <+> quotes (ppr co)) rt1 rt2 + ; lintRole co1 r (coercionRole co1) + ; lintRole co2 r (coercionRole co2) + ; return (FunCo r co1' co2') } -- See Note [Bad unsafe coercion] lintCoercion co@(UnivCo prov r ty1 ty2) - = do { k1 <- lintType ty1 - ; k2 <- lintType ty2 - ; case prov of - PhantomProv kco -> do { lintRole co Phantom r - ; check_kinds kco k1 k2 } - - ProofIrrelProv kco -> do { lintL (isCoercionTy ty1) $ - mkBadProofIrrelMsg ty1 co - ; lintL (isCoercionTy ty2) $ - mkBadProofIrrelMsg ty2 co - ; check_kinds kco k1 k2 } - - PluginProv _ -> return () -- no extra checks + = do { ty1' <- lintType ty1 + ; ty2' <- lintType ty2 + ; let k1 = typeKind ty1' + k2 = typeKind ty2' + ; prov' <- lint_prov k1 k2 prov ; when (r /= Phantom && classifiesTypeWithValues k1 && classifiesTypeWithValues k2) (checkTypes ty1 ty2) - ; return (k1, k2, ty1, ty2, r) } + + ; return (UnivCo prov' r ty1' ty2') } where report s = hang (text $ "Unsafe coercion: " ++ s) 2 (vcat [ text "From:" <+> ppr ty1 @@ -1925,39 +1954,53 @@ lintCoercion co@(UnivCo prov r ty1 ty2) _ -> return () } - check_kinds kco k1 k2 = do { (k1', k2') <- lintStarCoercion kco - ; ensureEqTys k1 k1' (mkBadUnivCoMsg CLeft co) - ; ensureEqTys k2 k2' (mkBadUnivCoMsg CRight co) } + lint_prov k1 k2 (PhantomProv kco) + = do { kco' <- lintStarCoercion kco + ; lintRole co Phantom r + ; check_kinds kco' k1 k2 + ; return (PhantomProv kco') } + + lint_prov k1 k2 (ProofIrrelProv kco) + = do { lintL (isCoercionTy ty1) (mkBadProofIrrelMsg ty1 co) + ; lintL (isCoercionTy ty2) (mkBadProofIrrelMsg ty2 co) + ; kco' <- lintStarCoercion kco + ; check_kinds kco k1 k2 + ; return (ProofIrrelProv kco') } + + lint_prov _ _ prov@(PluginProv _) = return prov + + check_kinds kco k1 k2 + = do { let Pair k1' k2' = coercionKind kco + ; ensureEqTys k1 k1' (mkBadUnivCoMsg CLeft co) + ; ensureEqTys k2 k2' (mkBadUnivCoMsg CRight co) } lintCoercion (SymCo co) - = do { (k1, k2, ty1, ty2, r) <- lintCoercion co - ; return (k2, k1, ty2, ty1, r) } + = do { co' <- lintCoercion co + ; return (SymCo co') } lintCoercion co@(TransCo co1 co2) - = do { (k1a, _k1b, ty1a, ty1b, r1) <- lintCoercion co1 - ; (_k2a, k2b, ty2a, ty2b, r2) <- lintCoercion co2 + = do { co1' <- lintCoercion co1 + ; co2' <- lintCoercion co2 + ; let ty1b = coercionRKind co1' + ty2a = coercionLKind co2' ; ensureEqTys ty1b ty2a (hang (text "Trans coercion mis-match:" <+> ppr co) - 2 (vcat [ppr ty1a, ppr ty1b, ppr ty2a, ppr ty2b])) - ; lintRole co r1 r2 - ; return (k1a, k2b, ty1a, ty2b, r1) } + 2 (vcat [ppr (coercionKind co1'), ppr (coercionKind co2')])) + ; lintRole co (coercionRole co1) (coercionRole co2) + ; return (TransCo co1' co2') } lintCoercion the_co@(NthCo r0 n co) - = do { (_, _, s, t, r) <- lintCoercion co + = do { co' <- lintCoercion co + ; let (Pair s t, r) = coercionKindRole co' ; case (splitForAllTy_maybe s, splitForAllTy_maybe t) of - { (Just (tcv_s, _ty_s), Just (tcv_t, _ty_t)) + { (Just _, Just _) -- works for both tyvar and covar | n == 0 , (isForAllTy_ty s && isForAllTy_ty t) || (isForAllTy_co s && isForAllTy_co t) -> do { lintRole the_co Nominal r0 - ; return (ks, kt, ts, tt, r0) } - where - ts = varType tcv_s - tt = varType tcv_t - ks = typeKind ts - kt = typeKind tt + ; return (NthCo r0 n co') } ; _ -> case (splitTyConApp_maybe s, splitTyConApp_maybe t) of { (Just (tc_s, tys_s), Just (tc_t, tys_t)) @@ -1967,62 +2010,51 @@ lintCoercion the_co@(NthCo r0 n co) , tys_s `equalLength` tys_t , tys_s `lengthExceeds` n -> do { lintRole the_co tr r0 - ; return (ks, kt, ts, tt, r0) } - where - ts = getNth tys_s n - tt = getNth tys_t n - tr = nthRole r tc_s n - ks = typeKind ts - kt = typeKind tt + ; return (NthCo r0 n co') } + where + tr = nthRole r tc_s n ; _ -> failWithL (hang (text "Bad getNth:") 2 (ppr the_co $$ ppr s $$ ppr t)) }}} lintCoercion the_co@(LRCo lr co) - = do { (_,_,s,t,r) <- lintCoercion co + = do { co' <- lintCoercion co + ; let Pair s t = coercionKind co' + r = coercionRole co' ; lintRole co Nominal r ; case (splitAppTy_maybe s, splitAppTy_maybe t) of - (Just s_pr, Just t_pr) - -> return (ks_pick, kt_pick, s_pick, t_pick, Nominal) - where - s_pick = pickLR lr s_pr - t_pick = pickLR lr t_pr - ks_pick = typeKind s_pick - kt_pick = typeKind t_pick - + (Just _, Just _) -> return (LRCo lr co') _ -> failWithL (hang (text "Bad LRCo:") 2 (ppr the_co $$ ppr s $$ ppr t)) } lintCoercion (InstCo co arg) - = do { (k3, k4, t1',t2', r) <- lintCoercion co - ; (k1',k2',s1,s2, r') <- lintCoercion arg - ; lintRole arg Nominal r' - ; in_scope <- getInScope - ; case (splitForAllTy_ty_maybe t1', splitForAllTy_ty_maybe t2') of + = do { co' <- lintCoercion co + ; arg' <- lintCoercion arg + ; let Pair t1' t2' = coercionKind co' + Pair s1 s2 = coercionKind arg + + ; lintRole arg Nominal (coercionRole arg') + + ; case (splitForAllTy_ty_maybe t1', splitForAllTy_ty_maybe t2') of -- forall over tvar - { (Just (tv1,t1), Just (tv2,t2)) - | k1' `eqType` tyVarKind tv1 - , k2' `eqType` tyVarKind tv2 - -> return (k3, k4, - substTyWithInScope in_scope [tv1] [s1] t1, - substTyWithInScope in_scope [tv2] [s2] t2, r) + { (Just (tv1,_), Just (tv2,_)) + | typeKind s1 `eqType` tyVarKind tv1 + , typeKind s2 `eqType` tyVarKind tv2 + -> return (InstCo co' arg') | otherwise -> failWithL (text "Kind mis-match in inst coercion") + ; _ -> case (splitForAllTy_co_maybe t1', splitForAllTy_co_maybe t2') of -- forall over covar - { (Just (cv1, t1), Just (cv2, t2)) - | k1' `eqType` varType cv1 - , k2' `eqType` varType cv2 - , CoercionTy s1' <- s1 - , CoercionTy s2' <- s2 - -> do { return $ - (liftedTypeKind, liftedTypeKind - -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep - , substTy (mkCvSubst in_scope $ unitVarEnv cv1 s1') t1 - , substTy (mkCvSubst in_scope $ unitVarEnv cv2 s2') t2 - , r) } + { (Just (cv1, _), Just (cv2, _)) + | typeKind s1 `eqType` varType cv1 + , typeKind s2 `eqType` varType cv2 + , CoercionTy _ <- s1 + , CoercionTy _ <- s2 + -> return (InstCo co' arg') | otherwise -> failWithL (text "Kind mis-match in inst coercion") + ; _ -> failWithL (text "Bad argument of inst") }}} lintCoercion co@(AxiomInstCo con ind cos) @@ -2030,73 +2062,69 @@ lintCoercion co@(AxiomInstCo con ind cos) (bad_ax (text "index out of range")) ; let CoAxBranch { cab_tvs = ktvs , cab_cvs = cvs - , cab_roles = roles - , cab_lhs = lhs - , cab_rhs = rhs } = coAxiomNthBranch con ind + , cab_roles = roles } = coAxiomNthBranch con ind ; unless (cos `equalLength` (ktvs ++ cvs)) $ bad_ax (text "lengths") + ; cos' <- mapM lintCoercion cos ; subst <- getTCvSubst ; let empty_subst = zapTCvSubst subst - ; (subst_l, subst_r) <- foldlM check_ki - (empty_subst, empty_subst) - (zip3 (ktvs ++ cvs) roles cos) - ; let lhs' = substTys subst_l lhs - rhs' = substTy subst_r rhs - fam_tc = coAxiomTyCon con + ; _ <- foldlM check_ki (empty_subst, empty_subst) + (zip3 (ktvs ++ cvs) roles cos') + ; let fam_tc = coAxiomTyCon con ; case checkAxInstCo co of Just bad_branch -> bad_ax $ text "inconsistent with" <+> pprCoAxBranch fam_tc bad_branch Nothing -> return () - ; let s2 = mkTyConApp fam_tc lhs' - ; return (typeKind s2, typeKind rhs', s2, rhs', coAxiomRole con) } + ; return (AxiomInstCo con ind cos') } where bad_ax what = addErrL (hang (text "Bad axiom application" <+> parens what) 2 (ppr co)) - check_ki (subst_l, subst_r) (ktv, role, arg) - = do { (k', k'', s', t', r) <- lintCoercion arg - ; lintRole arg role r + check_ki (subst_l, subst_r) (ktv, role, arg') + = do { let Pair s' t' = coercionKind arg' + sk' = typeKind s' + tk' = typeKind t' + ; lintRole arg' role (coercionRole arg') ; let ktv_kind_l = substTy subst_l (tyVarKind ktv) ktv_kind_r = substTy subst_r (tyVarKind ktv) - ; unless (k' `eqType` ktv_kind_l) - (bad_ax (text "check_ki1" <+> vcat [ ppr co, ppr k', ppr ktv, ppr ktv_kind_l ] )) - ; unless (k'' `eqType` ktv_kind_r) - (bad_ax (text "check_ki2" <+> vcat [ ppr co, ppr k'', ppr ktv, ppr ktv_kind_r ] )) + ; unless (sk' `eqType` ktv_kind_l) + (bad_ax (text "check_ki1" <+> vcat [ ppr co, ppr sk', ppr ktv, ppr ktv_kind_l ] )) + ; unless (tk' `eqType` ktv_kind_r) + (bad_ax (text "check_ki2" <+> vcat [ ppr co, ppr tk', ppr ktv, ppr ktv_kind_r ] )) ; return (extendTCvSubst subst_l ktv s', extendTCvSubst subst_r ktv t') } lintCoercion (KindCo co) - = do { (k1, k2, _, _, _) <- lintCoercion co - ; return (liftedTypeKind, liftedTypeKind, k1, k2, Nominal) } + = do { co' <- lintCoercion co + ; return (KindCo co') } lintCoercion (SubCo co') - = do { (k1,k2,s,t,r) <- lintCoercion co' - ; lintRole co' Nominal r - ; return (k1,k2,s,t,Representational) } - -lintCoercion this@(AxiomRuleCo co cs) - = do { eqs <- mapM lintCoercion cs - ; lintRoles 0 (coaxrAsmpRoles co) eqs - ; case coaxrProves co [ Pair l r | (_,_,l,r,_) <- eqs ] of + = do { co' <- lintCoercion co' + ; lintRole co' Nominal (coercionRole co') + ; return (SubCo co') } + +lintCoercion this@(AxiomRuleCo ax cos) + = do { cos' <- mapM lintCoercion cos + ; lint_roles 0 (coaxrAsmpRoles ax) cos' + ; case coaxrProves ax (map coercionKind cos') of Nothing -> err "Malformed use of AxiomRuleCo" [ ppr this ] - Just (Pair l r) -> - return (typeKind l, typeKind r, l, r, coaxrRole co) } + Just _ -> return (AxiomRuleCo ax cos') } where err m xs = failWithL $ - hang (text m) 2 $ vcat (text "Rule:" <+> ppr (coaxrName co) : xs) + hang (text m) 2 $ vcat (text "Rule:" <+> ppr (coaxrName ax) : xs) - lintRoles n (e : es) ((_,_,_,_,r) : rs) - | e == r = lintRoles (n+1) es rs + lint_roles n (e : es) (co : cos) + | e == coercionRole co = lint_roles (n+1) es cos | otherwise = err "Argument roles mismatch" [ text "In argument:" <+> int (n+1) , text "Expected:" <+> ppr e - , text "Found:" <+> ppr r ] - lintRoles _ [] [] = return () - lintRoles n [] rs = err "Too many coercion arguments" + , text "Found:" <+> ppr (coercionRole co) ] + lint_roles _ [] [] = return () + lint_roles n [] rs = err "Too many coercion arguments" [ text "Expected:" <+> int n , text "Provided:" <+> int (n + length rs) ] - lintRoles n es [] = err "Not enough coercion arguments" + lint_roles n es [] = err "Not enough coercion arguments" [ text "Expected:" <+> int (n + length es) , text "Provided:" <+> int n ] @@ -2105,13 +2133,6 @@ lintCoercion (HoleCo h) ; lintCoercion (CoVarCo (coHoleCoVar h)) } ----------- -lintUnliftedCoVar :: CoVar -> LintM () -lintUnliftedCoVar cv - = when (not (isUnliftedType (coVarKind cv))) $ - failWithL (text "Bad lifted equality:" <+> ppr cv - <+> dcolon <+> ppr (coVarKind cv)) - {- ************************************************************************ * * @@ -2128,12 +2149,19 @@ data LintEnv , le_subst :: TCvSubst -- Current TyCo substitution -- See Note [Linting type lets] - -- /Only/ substitutes for type variables; - -- but might clone CoVars - -- We also use le_subst to keep track of - -- in-scope TyVars and CoVars + -- /Only/ substitutes for type variables; + -- but might clone CoVars + -- We also use le_subst to keep track of + -- in-scope TyVars and CoVars (but not Ids) + -- Range of the TCvSubst is LintedType/LintedCo + + , le_ids :: VarEnv (Id, LintedType) -- In-scope Ids + -- Used to check that occurrences have an enclosing binder. + -- The Id is /pre-substitution/, used to check that + -- the occurrence has an identical type to the binder + -- The LintedType is used to return the type of the occurrence, + -- without having to lint it again. - , le_ids :: IdSet -- In-scope Ids , le_joins :: IdSet -- Join points in scope that are valid -- A subset of the InScopeSet in le_subst -- See Note [Join points] @@ -2262,6 +2290,7 @@ instance HasDynFlags LintM where data LintLocInfo = RhsOf Id -- The variable bound + | OccOf Id -- Occurrence of id | LambdaBodyOf Id -- The lambda-binder | UnfoldingOf Id -- Unfolding of a binder | BodyOfLetRec [Id] -- One of the binders @@ -2274,7 +2303,6 @@ data LintLocInfo | ImportedUnfolding SrcLoc -- Some imported unfolding (ToDo: say which) | TopLevelBindings | InType Type -- Inside a type - | InKind Type Kind -- Inside a kind | InCo Coercion -- Inside a coercion initL :: DynFlags -> LintFlags -> [Var] @@ -2289,7 +2317,7 @@ initL dflags flags vars m (tcvs, ids) = partition isTyCoVar vars env = LE { le_flags = flags , le_subst = mkEmptyTCvSubst (mkInScopeSet (mkVarSet tcvs)) - , le_ids = mkVarSet ids + , le_ids = mkVarEnv [(id, (id,idType id)) | id <- ids] , le_joins = emptyVarSet , le_loc = [] , le_dynflags = dflags } @@ -2337,7 +2365,7 @@ addWarnL msg = LintM $ \ env (warns,errs) -> addMsg :: Bool -> LintEnv -> Bag MsgDoc -> MsgDoc -> Bag MsgDoc addMsg is_error env msgs msg - = ASSERT( notNull loc_msgs ) + = ASSERT2( notNull loc_msgs, msg ) msgs `snocBag` mk_msg msg where loc_msgs :: [(SrcLoc, SDoc)] -- Innermost first @@ -2369,18 +2397,17 @@ inCasePat = LintM $ \ env errs -> (Just (is_case_pat env), errs) is_case_pat (LE { le_loc = CasePat {} : _ }) = True is_case_pat _other = False -addInScopeTyCoVar :: Var -> LintM a -> LintM a -addInScopeTyCoVar var m - = LintM $ \ env errs -> - unLintM m (env { le_subst = extendTCvInScope (le_subst env) var }) errs - -addInScopeId :: Id -> LintM a -> LintM a -addInScopeId id m - = LintM $ \ env errs -> - unLintM m (env { le_ids = extendVarSet (le_ids env) id - , le_joins = delVarSet (le_joins env) id }) errs +addInScopeId :: Id -> LintedType -> LintM a -> LintM a +addInScopeId id linted_ty m + = LintM $ \ env@(LE { le_ids = id_set, le_joins = join_set }) errs -> + unLintM m (env { le_ids = extendVarEnv id_set id (id, linted_ty) + , le_joins = add_joins join_set }) errs + where + add_joins join_set + | isJoinId id = extendVarSet join_set id -- Overwrite with new arity + | otherwise = delVarSet join_set id -- Remove any existing binding -getInScopeIds :: LintM IdSet +getInScopeIds :: LintM (VarEnv (Id,LintedType)) getInScopeIds = LintM (\env errs -> (Just (le_ids env), errs)) extendTvSubstL :: TyVar -> Type -> LintM a -> LintM a @@ -2400,13 +2427,6 @@ markAllJoinsBadIf :: Bool -> LintM a -> LintM a markAllJoinsBadIf True m = markAllJoinsBad m markAllJoinsBadIf False m = m -addGoodJoins :: [Var] -> LintM a -> LintM a -addGoodJoins vars thing_inside - = LintM $ \ env errs -> unLintM thing_inside (add_joins env) errs - where - add_joins env = env { le_joins = le_joins env `extendVarSetList` join_ids } - join_ids = filter isJoinId vars - getValidJoins :: LintM IdSet getValidJoins = LintM (\ env errs -> (Just (le_joins env), errs)) @@ -2416,20 +2436,17 @@ getTCvSubst = LintM (\ env errs -> (Just (le_subst env), errs)) getInScope :: LintM InScopeSet getInScope = LintM (\ env errs -> (Just (getTCvInScope $ le_subst env), errs)) -applySubstTy :: InType -> LintM OutType -applySubstTy ty = do { subst <- getTCvSubst; return (substTy subst ty) } - -applySubstCo :: InCoercion -> LintM OutCoercion -applySubstCo co = do { subst <- getTCvSubst; return (substCo subst co) } - -lookupIdInScope :: Id -> LintM Id +lookupIdInScope :: Id -> LintM (Id, LintedType) lookupIdInScope id_occ = do { in_scope_ids <- getInScopeIds - ; case lookupVarSet in_scope_ids id_occ of - Just id_bnd -> do { checkL (not (bad_global id_bnd)) global_in_scope - ; return id_bnd } + ; case lookupVarEnv in_scope_ids id_occ of + Just (id_bndr, linted_ty) + -> do { checkL (not (bad_global id_bndr)) global_in_scope + ; return (id_bndr, linted_ty) } Nothing -> do { checkL (not is_local) local_out_of_scope - ; return id_occ } } + ; return (id_occ, idType id_occ) } } + -- We don't bother to lint the type + -- of global (i.e. imported) Ids where is_local = mustHaveLocalBinding id_occ local_out_of_scope = text "Out of scope:" <+> pprBndr LetBind id_occ @@ -2457,16 +2474,7 @@ lookupJoinId id Just id' -> return (isJoinId_maybe id') Nothing -> return Nothing } -lintTyCoVarInScope :: TyCoVar -> LintM TyCoVar -lintTyCoVarInScope var - = do { subst <- getTCvSubst - ; case lookupInScope (getTCvInScope subst) var of - Just var' -> return var' - Nothing -> failWithL $ - hang (text "The TyCo variable" <+> pprBndr LetBind var) - 2 (text "is out of scope") } - -ensureEqTys :: OutType -> OutType -> MsgDoc -> LintM () +ensureEqTys :: LintedType -> LintedType -> MsgDoc -> LintM () -- check ty2 is subtype of ty1 (ie, has same structure but usage -- annotations need only be consistent, not equal) -- Assumes ty1,ty2 are have already had the substitution applied @@ -2496,6 +2504,9 @@ dumpLoc :: LintLocInfo -> (SrcLoc, SDoc) dumpLoc (RhsOf v) = (getSrcLoc v, text "In the RHS of" <+> pp_binders [v]) +dumpLoc (OccOf v) + = (getSrcLoc v, text "In an occurrence of" <+> pp_binder v) + dumpLoc (LambdaBodyOf b) = (getSrcLoc b, text "In the body of lambda with binder" <+> pp_binder b) @@ -2530,8 +2541,6 @@ dumpLoc TopLevelBindings = (noSrcLoc, Outputable.empty) dumpLoc (InType ty) = (noSrcLoc, text "In the type" <+> quotes (ppr ty)) -dumpLoc (InKind ty ki) - = (noSrcLoc, text "In the kind of" <+> parens (ppr ty <+> dcolon <+> ppr ki)) dumpLoc (InCo co) = (noSrcLoc, text "In the coercion" <+> quotes (ppr co)) @@ -2776,7 +2785,7 @@ mkJoinBndrOccMismatchMsg bndr join_arity_bndr join_arity_occ , text "Arity at binding site:" <+> ppr join_arity_bndr , text "Arity at occurrence: " <+> ppr join_arity_occ ] -mkBndrOccTypeMismatchMsg :: Var -> Var -> OutType -> OutType -> SDoc +mkBndrOccTypeMismatchMsg :: Var -> Var -> LintedType -> LintedType -> SDoc mkBndrOccTypeMismatchMsg bndr var bndr_ty var_ty = vcat [ text "Mismatch in type between binder and occurrence" , text "Binder:" <+> ppr bndr <+> dcolon <+> ppr bndr_ty ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2447,7 +2447,7 @@ normally it would make no sense to have forall r. (ty :: K r) because the kind of the forall would escape the binding of 'r'. But in this case it's fine because (K r) exapands -to Type, so we expliclity /permit/ the type +to Type, so we explicitly /permit/ the type forall r. T r To accommodate such a type, in typeKind (forall a.ty) we use @@ -2455,8 +2455,13 @@ occCheckExpand to expand any type synonyms in the kind of 'ty' to eliminate 'a'. See kinding rule (FORALL) in Note [Kinding rules for types] -And in GHC.Tc.Validity.checkEscapingKind, we use also use -occCheckExpand, for the same reason. +See also + * GHC.Core.Type.occCheckExpand + * GHC.Core.Utils.coreAltsType + * GHC.Tc.Validity.checkEscapingKind +all of which grapple with with the same problem. + +See #14939. -} ----------------------------- ===================================== testsuite/tests/indexed-types/should_compile/T17923.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# OPTIONS_GHC -Wall #-} +module Bug where + +import Data.Kind + +-- type SingFunction2 f = forall t1 t2. Sing t1 -> Sing t2 -> Sing (f `Apply` t1 `Apply` t2) +type SingFunction2 f = forall t1. Sing t1 -> forall t2. Sing t2 -> Sing (f `Apply` t1 `Apply` t2) +singFun2 :: forall f. SingFunction2 f -> Sing f +singFun2 f = SLambda (\x -> SLambda (f x)) + +type family Sing :: k -> Type +data TyFun :: Type -> Type -> Type +type a ~> b = TyFun a b -> Type +infixr 0 ~> + +type family Apply (f :: a ~> b) (x :: a) :: b +data Sym4 a +data Sym3 a + +type instance Apply Sym3 _ = Sym4 + +newtype SLambda (f :: k1 ~> k2) = + SLambda { applySing :: forall t. Sing t -> Sing (Apply f t) } +type instance Sing = SLambda + +und :: a +und = undefined + +data E +data ShowCharSym0 :: E ~> E ~> E + +sShow_tuple :: SLambda Sym4 +sShow_tuple + = applySing (singFun2 @Sym3 und) + (und (singFun2 @Sym3 + (und (applySing (singFun2 @Sym3 und) + (applySing (singFun2 @ShowCharSym0 und) und))))) ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -294,3 +294,4 @@ test('T16828', normal, compile, ['']) test('T17008b', normal, compile, ['']) test('T17056', normal, compile, ['']) test('T17405', normal, multimod_compile, ['T17405c', '-v0']) +test('T17923', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd4f92b5f4251f1a37d1e08ee97d99f2ccb41f26 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd4f92b5f4251f1a37d1e08ee97d99f2ccb41f26 You're receiving 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 12 15:21:46 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 11:21:46 -0400 Subject: [Git][ghc/ghc][master] Implement extensible interface files Message-ID: <5e93320a2deec_6167134ebbc445713a3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 8 changed files: - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/utils/Binary.hs - docs/users_guide/extending_ghc.rst - testsuite/tests/showIface/DocsInHiFile0.stdout - testsuite/tests/showIface/DocsInHiFile1.stdout Changes: ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -147,7 +147,14 @@ module GHC.Driver.Types ( -- * COMPLETE signature CompleteMatch(..), CompleteMatchMap, - mkCompleteMatchMap, extendCompleteMatchMap + mkCompleteMatchMap, extendCompleteMatchMap, + + -- * Exstensible Iface fields + ExtensibleFields(..), FieldName, + emptyExtensibleFields, + readField, readIfaceField, readIfaceFieldWith, + writeField, writeIfaceField, writeIfaceFieldWith, + deleteField, deleteIfaceField, ) where #include "HsVersions.h" @@ -215,8 +222,10 @@ import GHC.Serialized ( Serialized ) import qualified GHC.LanguageExtensions as LangExt import Foreign -import Control.Monad ( guard, liftM, ap ) +import Control.Monad ( guard, liftM, ap, forM, forM_, replicateM ) import Data.IORef +import Data.Map ( Map ) +import qualified Data.Map as Map import Data.Time import Exception import System.FilePath @@ -1090,9 +1099,17 @@ data ModIface_ (phase :: ModIfacePhase) mi_arg_docs :: ArgDocMap, -- ^ Docs on arguments. - mi_final_exts :: !(IfaceBackendExts phase) + mi_final_exts :: !(IfaceBackendExts phase), -- ^ Either `()` or `ModIfaceBackend` for -- a fully instantiated interface. + + 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 + -- internal `Binary` class (increasing compatibility with types + -- using `Name` and `FastString`, such as HIE), this format is + -- chosen over `ByteString`s. } -- | Old-style accessor for whether or not the ModIface came from an hs-boot @@ -1164,6 +1181,9 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_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_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1264,6 +1284,8 @@ instance Binary ModIface where mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, + mi_ext_fields = emptyExtensibleFields, -- placeholder because this is dealt + -- with specially when the file is read mi_final_exts = ModIfaceBackend { mi_iface_hash = iface_hash, mi_mod_hash = mod_hash, @@ -1307,7 +1329,9 @@ emptyPartialModIface mod mi_doc_hdr = Nothing, mi_decl_docs = emptyDeclDocMap, mi_arg_docs = emptyArgDocMap, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields + } emptyFullModIface :: Module -> ModIface emptyFullModIface mod = @@ -3279,7 +3303,105 @@ phaseForeignLanguage phase = case phase of -- avoid major space leaks. instance (NFData (IfaceBackendExts (phase :: ModIfacePhase)), NFData (IfaceDeclExts (phase :: ModIfacePhase))) => NFData (ModIface_ phase) where rnf (ModIface f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 - f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23) = + f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24) = rnf f1 `seq` rnf f2 `seq` f3 `seq` f4 `seq` f5 `seq` f6 `seq` rnf f7 `seq` f8 `seq` f9 `seq` rnf f10 `seq` rnf f11 `seq` f12 `seq` rnf f13 `seq` rnf f14 `seq` rnf f15 `seq` rnf f16 `seq` f17 `seq` rnf f18 `seq` rnf f19 `seq` f20 `seq` f21 `seq` f22 `seq` rnf f23 + `seq` rnf f24 + +{- +************************************************************************ +* * +\subsection{Extensible Iface Fields} +* * +************************************************************************ +-} + +type FieldName = String + +newtype ExtensibleFields = ExtensibleFields { getExtensibleFields :: (Map FieldName BinData) } + +instance Binary ExtensibleFields where + put_ bh (ExtensibleFields fs) = do + put_ bh (Map.size fs :: Int) + + -- Put the names of each field, and reserve a space + -- for a payload pointer after each name: + header_entries <- forM (Map.toList fs) $ \(name, dat) -> do + put_ bh name + field_p_p <- tellBin 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 + putAt bh field_p_p field_p + seekBin bh field_p + put_ bh dat + + get bh = do + n <- get bh :: IO Int + + -- Get the names and field pointers: + header_entries <- replicateM n $ do + (,) <$> get bh <*> get bh + + -- Seek to and get each field's payload: + fields <- forM header_entries $ \(name, field_p) -> do + seekBin bh field_p + dat <- get bh + return (name, dat) + + return . ExtensibleFields . Map.fromList $ fields + +instance NFData ExtensibleFields where + rnf (ExtensibleFields fs) = rnf fs + +emptyExtensibleFields :: ExtensibleFields +emptyExtensibleFields = ExtensibleFields Map.empty + +-------------------------------------------------------------------------------- +-- | Reading + +readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) +readIfaceField name = readIfaceFieldWith name get + +readField :: Binary a => FieldName -> ExtensibleFields -> IO (Maybe a) +readField name = readFieldWith name get + +readIfaceFieldWith :: FieldName -> (BinHandle -> IO a) -> ModIface -> IO (Maybe a) +readIfaceFieldWith name read iface = readFieldWith name read (mi_ext_fields iface) + +readFieldWith :: FieldName -> (BinHandle -> IO a) -> ExtensibleFields -> IO (Maybe a) +readFieldWith name read fields = sequence $ ((read =<<) . dataHandle) <$> + Map.lookup name (getExtensibleFields fields) + +-------------------------------------------------------------------------------- +-- | Writing + +writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface +writeIfaceField name x = writeIfaceFieldWith name (`put_` x) + +writeField :: Binary a => FieldName -> a -> ExtensibleFields -> IO ExtensibleFields +writeField name x = writeFieldWith name (`put_` x) + +writeIfaceFieldWith :: FieldName -> (BinHandle -> IO ()) -> ModIface -> IO ModIface +writeIfaceFieldWith name write iface = do + fields <- writeFieldWith name write (mi_ext_fields iface) + return iface{ mi_ext_fields = fields } + +writeFieldWith :: FieldName -> (BinHandle -> IO ()) -> ExtensibleFields -> IO ExtensibleFields +writeFieldWith name write fields = do + bh <- openBinMem (1024 * 1024) + write bh + -- + bd <- handleData bh + return $ ExtensibleFields (Map.insert name bd $ getExtensibleFields fields) + +deleteField :: FieldName -> ExtensibleFields -> ExtensibleFields +deleteField name (ExtensibleFields fs) = ExtensibleFields $ Map.delete name fs + +deleteIfaceField :: FieldName -> ModIface -> ModIface +deleteIfaceField name iface = iface { mi_ext_fields = deleteField name (mi_ext_fields iface) } ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -148,7 +148,15 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do wantedGot "Way" way_descr check_way ppr when (checkHiWay == CheckHiWay) $ errorOnMismatch "mismatched interface file ways" way_descr check_way - getWithUserData ncu bh + + extFields_p <- get bh + + mod_iface <- getWithUserData ncu bh + + seekBin bh extFields_p + extFields <- get bh + + return mod_iface{mi_ext_fields = extFields} -- | This performs a get action after reading the dictionary and symbol @@ -200,8 +208,16 @@ writeBinIface dflags hi_path mod_iface = do let way_descr = getWayDescr dflags put_ bh way_descr + extFields_p_p <- tellBin bh + put_ bh extFields_p_p putWithUserData (debugTraceMsg dflags 3) bh mod_iface + + extFields_p <- tellBin bh + putAt bh extFields_p_p extFields_p + seekBin bh extFields_p + put_ bh (mi_ext_fields mod_iface) + -- And send the result to the file writeBinMem bh hi_path ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Driver.Types import GHC.Types.Basic hiding (SuccessFlag(..)) import GHC.Tc.Utils.Monad +import Binary ( BinData(..) ) import Constants import PrelNames import PrelInfo @@ -83,6 +84,7 @@ import GHC.Driver.Plugins import Control.Monad import Control.Exception import Data.IORef +import Data.Map ( toList ) import System.FilePath import System.Directory @@ -1159,6 +1161,7 @@ pprModIface iface at ModIface{ mi_final_exts = exts } , text "module header:" $$ nest 2 (ppr (mi_doc_hdr iface)) , text "declaration docs:" $$ nest 2 (ppr (mi_decl_docs iface)) , text "arg docs:" $$ nest 2 (ppr (mi_arg_docs iface)) + , text "extensible fields:" $$ nest 2 (pprExtensibleFields (mi_ext_fields iface)) ] where pp_hsc_src HsBootFile = text "[boot]" @@ -1248,6 +1251,11 @@ pprIfaceAnnotation :: IfaceAnnotation -> SDoc pprIfaceAnnotation (IfaceAnnotation { ifAnnotatedTarget = target, ifAnnotatedValue = serialized }) = ppr target <+> text "annotated by" <+> ppr serialized +pprExtensibleFields :: ExtensibleFields -> SDoc +pprExtensibleFields (ExtensibleFields fs) = vcat . map pprField $ toList fs + where + pprField (name, (BinData size _data)) = text name <+> text "-" <+> ppr size <+> text "bytes" + {- ********************************************************* * * ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -268,7 +268,8 @@ mkIface_ hsc_env mi_doc_hdr = doc_hdr, mi_decl_docs = decl_docs, mi_arg_docs = arg_docs, - mi_final_exts = () } + mi_final_exts = (), + mi_ext_fields = emptyExtensibleFields } where cmp_rule = comparing ifRuleName -- Compare these lexicographically by OccName, *not* by unique, ===================================== compiler/utils/Binary.hs ===================================== @@ -27,6 +27,8 @@ module Binary {-type-} BinHandle, SymbolTable, Dictionary, + BinData(..), dataHandle, handleData, + openBinMem, -- closeBin, @@ -73,6 +75,7 @@ import Fingerprint import GHC.Types.Basic import GHC.Types.SrcLoc +import Control.DeepSeq import Foreign import Data.Array import Data.ByteString (ByteString) @@ -95,6 +98,44 @@ import GHC.Serialized type BinArray = ForeignPtr Word8 + + +--------------------------------------------------------------- +-- BinData +--------------------------------------------------------------- + +data BinData = BinData Int BinArray + +instance NFData BinData where + rnf (BinData sz _) = rnf sz + +instance Binary BinData where + put_ bh (BinData sz dat) = do + put_ bh sz + putPrim bh sz $ \dest -> + withForeignPtr dat $ \orig -> + copyBytes dest orig sz + -- + get bh = do + sz <- get bh + dat <- mallocForeignPtrBytes sz + getPrim bh sz $ \orig -> + withForeignPtr dat $ \dest -> + copyBytes dest orig sz + return (BinData sz dat) + +dataHandle :: BinData -> IO BinHandle +dataHandle (BinData size bin) = do + ixr <- newFastMutInt + szr <- newFastMutInt + writeFastMutInt ixr 0 + writeFastMutInt szr size + binr <- newIORef bin + return (BinMem noUserData ixr szr binr) + +handleData :: BinHandle -> IO BinData +handleData (BinMem _ ixr _ binr) = BinData <$> readFastMutInt ixr <*> readIORef binr + --------------------------------------------------------------- -- BinHandle --------------------------------------------------------------- ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -749,6 +749,33 @@ NOT be invoked with your own modules. In the ``ModIface`` datatype you can find lots of useful information, including the exported definitions and type class instances. +The ``ModIface`` datatype also contains facilities for extending it with extra +data, stored in a ``Map`` of serialised fields, indexed by field names and using +GHC's internal ``Binary`` class. The interface to work with these fields is: + +:: + + readIfaceField :: Binary a => FieldName -> ModIface -> IO (Maybe a) + writeIfaceField :: Binary a => FieldName -> a -> ModIface -> IO ModIface + deleteIfaceField :: FieldName -> ModIface -> ModIface + +The ``FieldName`` is open-ended, but typically it should contain the producing +package name, along with the actual field name. Then, the version number can either +be attached to the serialised data for that field, or in cases where multiple versions +of a field could exist in the same interface file, included in the field name. + +Depending on if the field version advances with the package version, or independently, +the version can be attached to either the package name or the field name. Examples of +each case: + +:: + + package/field + ghc-n.n.n/core + package/field-n + +To read an interface file from an external tool without linking to GHC, the format +is described at `Extensible Interface Files`_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ ===================================== testsuite/tests/showIface/DocsInHiFile0.stdout ===================================== @@ -2,3 +2,4 @@ module header: Nothing declaration docs: arg docs: +extensible fields: ===================================== testsuite/tests/showIface/DocsInHiFile1.stdout ===================================== @@ -33,4 +33,4 @@ arg docs: p: 0: " An argument" - +extensible fields: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0efaf301fec9ed9ea827392cbe03de3335e995c7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0efaf301fec9ed9ea827392cbe03de3335e995c7 You're receiving 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 12 15:22:21 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 11:22:21 -0400 Subject: [Git][ghc/ghc][master] Use conLikeUserTyVarBinders to quantify field selector types Message-ID: <5e93322dea7f6_6167e4e49b445758a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 12 changed files: - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/existential_quantification.rst - + docs/users_guide/exts/field_selectors_and_type_applications.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/rank_polymorphism.rst - docs/users_guide/exts/records.rst - + testsuite/tests/typecheck/should_compile/T18023.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/ConLike.hs ===================================== @@ -12,6 +12,7 @@ module GHC.Core.ConLike ( , conLikeArity , conLikeFieldLabels , conLikeInstOrigArgTys + , conLikeUserTyVarBinders , conLikeExTyCoVars , conLikeName , conLikeStupidTheta @@ -113,6 +114,18 @@ conLikeInstOrigArgTys (RealDataCon data_con) tys = conLikeInstOrigArgTys (PatSynCon pat_syn) tys = patSynInstArgTys pat_syn tys +-- | 'TyVarBinder's for the type variables of the 'ConLike'. For pattern +-- synonyms, this will always consist of the universally quantified variables +-- followed by the existentially quantified type variables. For data +-- constructors, the situation is slightly more complicated—see +-- @Note [DataCon user type variable binders]@ in "GHC.Core.DataCon". +conLikeUserTyVarBinders :: ConLike -> [TyVarBinder] +conLikeUserTyVarBinders (RealDataCon data_con) = + dataConUserTyVarBinders data_con +conLikeUserTyVarBinders (PatSynCon pat_syn) = + patSynUnivTyVarBinders pat_syn ++ patSynExTyVarBinders pat_syn + -- The order here is because of the order in `GHC.Tc.TyCl.PatSyn`. + -- | Existentially quantified type/coercion variables conLikeExTyCoVars :: ConLike -> [TyCoVar] conLikeExTyCoVars (RealDataCon dcon1) = dataConExTyCoVars dcon1 ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -384,7 +384,9 @@ data DataCon -- MkT :: forall a b. (a ~ [b]) => b -> T a -- MkT :: forall b. b -> T [b] -- Each equality is of the form (a ~ ty), where 'a' is one of - -- the universally quantified type variables + -- the universally quantified type variables. Moreover, the + -- only place in the DataCon where this 'a' will occur is in + -- dcUnivTyVars. See [The dcEqSpec domain invariant]. -- The next two fields give the type context of the data constructor -- (aside from the GADT constraints, @@ -595,6 +597,35 @@ dcUserTyVarBinders, as the name suggests, is the one that users will see most of the time. It's used when computing the type signature of a data constructor (see dataConUserType), and as a result, it's what matters from a TypeApplications perspective. + +Note [The dcEqSpec domain invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this example of a GADT constructor: + + data Y a where + MkY :: Bool -> Y Bool + +The user-written type of MkY is `Bool -> Y Bool`, but what is the underlying +Core type for MkY? There are two conceivable possibilities: + +1. MkY :: forall a. (a ~# Bool) => Bool -> Y a +2. MkY :: forall a. (a ~# Bool) => a -> Y a + +In practice, GHC picks (1) as the Core type for MkY. This is because we +maintain an invariant that the type variables in the domain of dcEqSpec will +only ever appear in the dcUnivTyVars. As a consequence, the type variables in +the domain of dcEqSpec will /never/ appear in the dcExTyCoVars, dcOtherTheta, +dcOrigArgTys, or dcOrigResTy; these can only ever mention variables from +dcUserTyVarBinders, which excludes things in the domain of dcEqSpec. +(See Note [DataCon user type variable binders].) This explains why GHC would +not pick (2) as the Core type, since the argument type `a` mentions a type +variable in the dcEqSpec. + +There are certain parts of the codebase where it is convenient to apply the +substitution arising from the dcEqSpec to the dcUnivTyVars in order to obtain +the user-written return type of a GADT constructor. A consequence of the +dcEqSpec domain invariant is that you /never/ need to apply the substitution +to any other part of the constructor type, as they don't require it. -} -- | Data Constructor Representation ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -641,11 +641,7 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields mk_alt upd_fld_env con = do { let (univ_tvs, ex_tvs, eq_spec, prov_theta, _req_theta, arg_tys, _) = conLikeFullSig con - user_tvs = - case con of - RealDataCon data_con -> dataConUserTyVars data_con - PatSynCon _ -> univ_tvs ++ ex_tvs - -- The order here is because of the order in `GHC.Tc.TyCl.PatSyn`. + user_tvs = binderVars $ conLikeUserTyVarBinders con in_subst = zipTvSubst univ_tvs in_inst_tys out_subst = zipTvSubst univ_tvs out_inst_tys ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -872,19 +872,17 @@ mkOneRecordSelector all_cons idDetails fl -- Selector type; Note [Polymorphic selectors] field_ty = conLikeFieldType con1 lbl - data_tvs = tyCoVarsOfTypesWellScoped inst_tys - data_tv_set= mkVarSet data_tvs + data_tvbs = filter (\tvb -> binderVar tvb `elemVarSet` data_tv_set) $ + conLikeUserTyVarBinders con1 + data_tv_set= tyCoVarsOfTypes inst_tys is_naughty = not (tyCoVarsOfType field_ty `subVarSet` data_tv_set) - (field_tvs, field_theta, field_tau) = tcSplitSigmaTy field_ty sel_ty | is_naughty = unitTy -- See Note [Naughty record selectors] - | otherwise = mkSpecForAllTys data_tvs $ + | otherwise = mkForAllTys data_tvbs $ mkPhiTy (conLikeStupidTheta con1) $ -- Urgh! - mkVisFunTy data_ty $ - mkSpecForAllTys field_tvs $ - mkPhiTy field_theta $ -- req_theta is empty for normal DataCon mkPhiTy req_theta $ - field_tau + mkVisFunTy data_ty $ + field_ty -- Make the binding: sel (C2 { fld = x }) = x -- sel (C7 { fld = x }) = x @@ -936,6 +934,16 @@ mkOneRecordSelector all_cons idDetails fl (univ_tvs, _, eq_spec, _, req_theta, _, data_ty) = conLikeFullSig con1 eq_subst = mkTvSubstPrs (map eqSpecPair eq_spec) + -- inst_tys corresponds to one of the following: + -- + -- * The arguments to the user-written return type (for GADT constructors). + -- In this scenario, eq_subst provides a mapping from the universally + -- quantified type variables to the argument types. Note that eq_subst + -- does not need to be applied to any other part of the DataCon + -- (see Note [The dcEqSpec domain invariant] in GHC.Core.DataCon). + -- * The universally quantified type variables + -- (for Haskell98-style constructors and pattern synonyms). In these + -- scenarios, eq_subst is an empty substitution. inst_tys = substTyVars eq_subst univ_tvs unit_rhs = mkLHsTupleExpr [] @@ -945,13 +953,44 @@ mkOneRecordSelector all_cons idDetails fl Note [Polymorphic selectors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We take care to build the type of a polymorphic selector in the right -order, so that visible type application works. - - data Ord a => T a = MkT { field :: forall b. (Num a, Show b) => (a, b) } - -We want - - field :: forall a. Ord a => T a -> forall b. (Num a, Show b) => (a, b) +order, so that visible type application works according to the specification in +the GHC User's Guide (see the "Field selectors and TypeApplications" section). +We won't bother rehashing the entire specification in this Note, but the tricky +part is dealing with GADT constructor fields. Here is an appropriately tricky +example to illustrate the challenges: + + {-# LANGUAGE PolyKinds #-} + data T a b where + MkT :: forall b a x. + { field1 :: forall c. (Num a, Show c) => (Either a c, Proxy b) + , field2 :: x + } + -> T a b + +Our goal is to obtain the following type for `field1`: + + field1 :: forall {k} (b :: k) a. + T a b -> forall c. (Num a, Show c) => (Either a c, Proxy b) + +(`field2` is naughty, per Note [Naughty record selectors], so we cannot turn +it into a top-level field selector.) + +Some potential gotchas, inspired by #18023: + +1. Since the user wrote `forall b a x.` in the type of `MkT`, we want the `b` + to appear before the `a` when quantified in the type of `field1`. +2. On the other hand, we *don't* want to quantify `x` in the type of `field1`. + This is because `x` does not appear in the GADT return type, so it is not + needed in the selector type. +3. Because of PolyKinds, the kind of `b` is generalized to `k`. Moreover, since + this `k` is not written in the source code, it is inferred (i.e., not + available for explicit type applications) and thus written as {k} in the type + of `field1`. + +In order to address these gotchas, we start by looking at the +conLikeUserTyVarBinders, which gives the order and specificity of each binder. +This effectively solves (1) and (3). To solve (2), we filter the binders to +leave only those that are needed for the selector type. Note [Naughty record selectors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -18,6 +18,34 @@ Full details Language ~~~~~~~~ +* Record field selectors are now given type signatures that preserve the + user-written order of quantified type variables. Moreover, field selector + type signatures no longer make inferred type variables avaiable for explicit + type application. See :ref:`field-selectors-and-type-applications` for more + details. + + In certain situations, this will constitute a breaking change as this can + affect :extension:`TypeApplications`. For instance, given the following + definitions: :: + + {-# LANGUAGE PolyKinds #-} + + newtype P a = MkP { unP :: Proxy a } + + newtype N :: Type -> Type -> Type where + MkN :: forall b a. { unN :: Either a b } -> N a b + + Previous versions of GHC would give the following types to ``unP`` and + ``unN``: :: + + unP :: forall k (a :: k). P a -> Proxy a + unN :: forall a b. N a b -> Either a b + + GHC will now give them the following types instead: :: + + unP :: forall {k} (a :: k). P a -> Proxy a + unN :: forall b a. N a b -> Either a b + * In obscure scenarios, GHC now rejects programs it previously accepted, but with unhelpful types. For example, if (with ``-XPartialTypeSignatures``) you were to write ``x :: forall (f :: forall a (b :: a -> Type). b _). f _``, GHC previously @@ -40,7 +68,7 @@ Language There is a chance we will tweak the lookup scheme in the future, to make this workaround unnecessary. - + Compiler ~~~~~~~~ ===================================== docs/users_guide/exts/existential_quantification.rst ===================================== @@ -116,7 +116,11 @@ example: :: } Here ``tag`` is a public field, with a well-typed selector function -``tag :: Counter a -> a``. The ``self`` type is hidden from the outside; +``tag :: Counter a -> a``. See :ref:`field-selectors-and-type-applications` +for a full description of how the types of top-level field selectors are +determined. + +The ``self`` type is hidden from the outside; any attempt to apply ``_this``, ``_inc`` or ``_display`` as functions will raise a compile-time error. In other words, *GHC defines a record selector function only for fields whose type does not mention the ===================================== docs/users_guide/exts/field_selectors_and_type_applications.rst ===================================== @@ -0,0 +1,122 @@ +.. _field-selectors-and-type-applications: + +Field selectors and ``TypeApplications`` +---------------------------------------- + +Field selectors can be used in conjunction with :extension:`TypeApplications`, +as described in :ref:`visible-type-application`. The type of a field selector +is constructed by using the surrounding definition as context. This section +provides a specification for how this construction works. We will explain it +by considering three different forms of field selector, each of which is a +minor variation of the same general theme. + +Field selectors for Haskell98-style data constructors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider the following example: :: + + data T a b = MkT { unT :: forall e. Either e a } + +This data type uses a Haskell98-style declaration. The only part of this data +type that is not Haskell98 code is ``unT``, whose type uses higher-rank +polymorphism (:ref:`arbitrary-rank-polymorphism`). To construct the type of +the ``unT`` field selector, we will assemble the following: + +1. The type variables quantified by the data type head + (``forall a b. <...>``). +2. The return type of the data constructor + (``<...> T a b -> <...>``). By virtue of this being a Haskell98-style + declaration, the order of type variables in the return type will always + coincide with the order in which they are quantified. +3. The type of the field + (``<...> forall e. Either e a``). + +The final type of ``unT`` is therefore +``forall a b. T a b -> forall e. Either e a``. As a result, one way to use +``unT`` with :extension:`TypeApplications` is +``unT @Int @Bool (MkT (Right 1)) @Char``. + +Field selectors for GADT constructors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Field selectors for GADT constructors (:ref:`gadt-style`) are slightly more +involved. Consider the following example: :: + + data G a b where + MkG :: forall x n a. (Eq a, Show n) + => { unG1 :: forall e. Either e (a, x), unG2 :: n } -> G a (Maybe x) + +The ``MkG`` GADT constructor has two records, ``unG1`` and ``unG2``. +However, only ``unG1`` can be used as a top-level field selector. ``unG2`` +cannot because it is a "hidden" selector (see :ref:`existential-records`); its +type mentions a free variable ``n`` that does not appear in the result type +``G a (Maybe x)``. On the other hand, the only free type variables in the type +of ``unG1`` are ``a`` and ``x``, so ``unG1`` is fine to use as a top-level +function. + +To construct the type of the ``unG1`` field selector, we will assemble +the following: + +1. The subset of type variables quantified by the GADT constructor that are + mentioned in the return type. Note that the order of these variables follows + the same principles as in :ref:`ScopedSort`. + If the constructor explicitly quantifies its type variables at the beginning + of the type, then the field selector type will quantify them in the same + order (modulo any variables that are dropped due to not being mentioned in + the return type). + If the constructor implicitly quantifies its type variables, then the field + selector type will quantify them in the left-to-right order that they appear + in the field itself. + + In this example, ``MkG`` explicitly quantifies ``forall x n a.``, and of + those type variables, ``a`` and ``x`` are mentioned in the return type. + Therefore, the type of ``unG1`` starts as ``forall x a. <...>``. + If ``MkG`` had not used an explicit ``forall``, then they would have instead + been ordered as ``forall a x. <...>``, since ``a`` appears to the left of + ``x`` in the field type. +2. The GADT return type + (``<...> G a (Maybe x) -> ...``). +3. The type of the field + (``<...> -> forall e. Either e (a, x)``). + +The final type of ``unG1`` is therefore +``forall x a. G a (Maybe x) -> forall e. Either e (a, x)``. As a result, one +way to use ``unG1`` with :extension:`TypeApplications` is +``unG1 @Int @Bool (MkG (Right (True, 42)) ()) @Char``. + +Field selectors for pattern synonyms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Certain record pattern synonyms (:ref:`record-patsyn`) can give rise to +top-level field selectors. Consider the following example: :: + + pattern P :: forall a. Read a + => forall n. (Eq a, Show n) + => (forall e. Either e (a, Bool)) -> n -> G a (Maybe Bool) + pattern P {unP1, unP2} = MkG unP1 unP2 + +We can only make field selectors for pattern synonym records that do not +mention any existential type variables whatsoever in their types, per +:ref:`record-patsyn`. (This is a stronger requirement than for GADT records, +whose types can mention existential type variables provided that they are also +mentioned in the return type.) We can see that ``unP2`` cannot be used as a +top-level field selector since its type has a free type variable ``n``, which +is existential. ``unP1`` is fine, on the other hand, as its type only has one +free variable, the universal type variable ``a``. + +To construct the type of the ``unP1`` field selector, we will assemble +the following: + +1. The universal type variables + (``forall a. <...>``). +2. The required constraints + (``<...> Read a => <...>``). +3. The pattern synonym return type + (``<...> G a (Maybe Bool) -> <...>``). +4. The type of the field + (``<...> -> forall e. Either e (a, Bool)``). + +The final type of ``unP1`` is therefore +``forall a. Read a => G a (Maybe Bool) -> forall e. Either e (a, Bool)``. As a +result, one way to use ``unP1`` with :extension:`TypeApplications` is +``unP1 @Double (MkG (Right (4.5, True)) ()) @Char``. ===================================== docs/users_guide/exts/gadt.rst ===================================== @@ -118,6 +118,9 @@ also sets :extension:`GADTSyntax` and :extension:`MonoLocalBinds`. num :: Term Int -> Term Int arg :: Term Bool -> Term Int + See :ref:`field-selectors-and-type-applications` for a full description of + how the types of top-level field selectors are determined. + - When pattern-matching against data constructors drawn from a GADT, for example in a ``case`` expression, the following rules apply: ===================================== docs/users_guide/exts/rank_polymorphism.rst ===================================== @@ -1,3 +1,5 @@ +.. _arbitrary-rank-polymorphism: + Arbitrary-rank polymorphism =========================== ===================================== docs/users_guide/exts/records.rst ===================================== @@ -7,6 +7,7 @@ Records :maxdepth: 1 traditional_record_syntax + field_selectors_and_type_applications disambiguate_record_fields duplicate_record_fields record_puns ===================================== testsuite/tests/typecheck/should_compile/T18023.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +module T18023 where + +import Data.Kind +import Data.Proxy + +newtype N :: Type -> Type -> Type where + MkN :: forall b a. { unN :: Either a b } -> N a b + +toN :: Either Int Bool -> N Int Bool +toN = MkN @Bool @Int + +fromN :: N Int Bool -> Either Int Bool +fromN = unN @Bool @Int + +newtype P a = MkP { unP :: Proxy a } + +toPTrue :: Proxy True -> P True +toPTrue = MkP @True + +fromPTrue :: P True -> Proxy True +fromPTrue = unP @True + +newtype P2 a b = MkP2 { unP2 :: (Proxy a, Proxy b) } + +toP2True :: (Proxy True, Proxy True) -> P2 True True +toP2True = MkP2 @True @True + +fromP2True :: P2 True True -> (Proxy True, Proxy True) +fromP2True = unP2 @True @True ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -702,3 +702,4 @@ test('T17792', normal, compile, ['']) test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) +test('T18023', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/54ca66a7d30d7f7cfbf3753ebe547f5a20d76b96 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/54ca66a7d30d7f7cfbf3753ebe547f5a20d76b96 You're receiving 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 12 15:23:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 11:23:01 -0400 Subject: [Git][ghc/ghc][master] hadrian: Don't --export-dynamic on Darwin Message-ID: <5e93325567405_61673f8199536d944580436@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - 2 changed files: - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Packages.hs Changes: ===================================== hadrian/src/Oracles/Setting.hs ===================================== @@ -11,6 +11,7 @@ module Oracles.Setting ( -- ** Target platform things anyTargetPlatform, anyTargetOs, anyTargetArch, anyHostOs, + isElfTarget, ArmVersion(..), targetArmVersion, ghcWithInterpreter, useLibFFIForAdjustors @@ -231,6 +232,13 @@ anyTargetArch = matchSetting TargetArch anyHostOs :: [String] -> Action Bool anyHostOs = matchSetting HostOs +-- | Check whether the target OS uses the ELF object format. +isElfTarget :: Action Bool +isElfTarget = anyTargetOs + [ "linux", "freebsd", "dragonfly", "openbsd", "netbsd", "solaris2", "kfreebsdgnu" + , "haiku", "linux-android" + ] + -- | Check whether the host OS supports the @-rpath@ linker option when -- using dynamic linking. -- ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -127,7 +127,12 @@ packageArgs = do -- refer to the RTS. This is harmless if you don't use it (adds a bit -- of overhead to startup and increases the binary sizes) but if you -- need it there's no alternative. - , package iserv ? mconcat + -- + -- The Solaris linker does not support --export-dynamic option. It also + -- does not need it since it exports all dynamic symbols by default + , package iserv + ? expr isElfTarget + ? notM (expr $ anyTargetOs ["freebsd", "solaris2"])? mconcat [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] -------------------------------- haddock ------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/35799dda07813e4c510237290a631d4d11fb92d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/35799dda07813e4c510237290a631d4d11fb92d2 You're receiving 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 12 15:23:37 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 12 Apr 2020 11:23:37 -0400 Subject: [Git][ghc/ghc][master] Add an INLINE pragma to Control.Category.>>> Message-ID: <5e933279b1daa_6167136dfb9c458524a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 6 changed files: - libraries/base/Control/Category.hs - libraries/base/GHC/Desugar.hs - + testsuite/tests/simplCore/should_compile/T18013.hs - + testsuite/tests/simplCore/should_compile/T18013.stderr - + testsuite/tests/simplCore/should_compile/T18013a.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== libraries/base/Control/Category.hs ===================================== @@ -77,3 +77,67 @@ instance Category Coercion where -- | Left-to-right composition (>>>) :: Category cat => cat a b -> cat b c -> cat a c f >>> g = g . f +{-# INLINE (>>>) #-} -- see Note [INLINE on >>>] + +{- Note [INLINE on >>>] +~~~~~~~~~~~~~~~~~~~~~~~ +It’s crucial that we include an INLINE pragma on >>>, which may be +surprising. After all, its unfolding is tiny, so GHC will be extremely +keen to inline it even without the pragma. Indeed, it is actually +/too/ keen: unintuitively, the pragma is needed to rein in inlining, +not to encourage it. + +How is that possible? The difference lies entirely in whether GHC will +inline unsaturated calls. With no pragma at all, we get the following +unfolding guidance: + ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=True) +But with the pragma, we restrict inlining to saturated calls: + ALWAYS_IF(arity=3,unsat_ok=False,boring_ok=True) +Why does this matter? Because the programmer may have put an INLINE +pragma on (.): + + instance Functor f => Category (Blah f) where + id = ... + Blah f . Blah g = buildBlah (\x -> ...) + {-# INLINE (.) #-} + +The intent here is to inline (.) at all saturated call sites. Perhaps +there is a RULE on buildBlah the programmer wants to fire, or maybe +they just expect the inlining to expose further simplifications. +Either way, code that uses >>> should not defeat this inlining, but if +we inline unsaturated calls, it might! Consider: + + let comp = (>>>) ($fCategoryBlah $dFunctor) in f `comp` (g `comp` h) + +While simplifying this expression, we’ll start with the RHS of comp. +Without the INLINE pragma on >>>, we’ll inline it immediately, even +though it isn’t saturated: + + let comp = \f g -> $fCategoryBlah_$c. $dFunctor g f + in f `comp` (g `comp` h) + +Now `$fCategoryBlah_$c. $dFunctor g f` /is/ a fully-saturated call, so +it will get inlined immediately, too: + + let comp = \(Blah g) (Blah f) -> buildBlah (\x -> ...) + in f `comp` (g `comp` h) + +All okay so far. But if the RHS of (.) is large, comp won’t be inlined +at its use sites, and any RULEs on `buildBlah` will never fire. Bad! + +What happens differently with the INLINE pragma on >>>? Well, we won’t +inline >>> immediately, since it isn’t saturated, which means comp’s +unfolding will be tiny. GHC will inline it at both use sites: + + (>>>) ($fCategoryBlah $dFunctor) f + ((>>>) ($fCategoryBlah $dFunctor) g h) + +And now the calls to >>> are saturated, so they’ll be inlined, +followed by (.), and any RULEs can fire as desired. Problem solved. + +This situation might seem academic --- who would ever write a +definition like comp? Probably nobody, but GHC generates such +definitions when desugaring proc notation, which causes real problems +(see #18013). That could be fixed by changing the proc desugaring, but +fixing it this way is the Right Thing, it might benefit other programs +in more subtle ways too, and it’s easier to boot. -} ===================================== libraries/base/GHC/Desugar.hs ===================================== @@ -10,13 +10,13 @@ -- Module : GHC.Desugar -- Copyright : (c) The University of Glasgow, 2007 -- License : see libraries/base/LICENSE --- +-- -- Maintainer : cvs-ghc at haskell.org -- Stability : internal -- Portability : non-portable (GHC extensions) -- -- Support code for desugaring in GHC --- +-- ----------------------------------------------------------------------------- module GHC.Desugar ((>>>), AnnotationWrapper(..), toAnnotationWrapper) where @@ -28,14 +28,14 @@ import Data.Data (Data) -- A version of Control.Category.>>> overloaded on Arrow (>>>) :: forall arr. Arrow arr => forall a b c. arr a b -> arr b c -> arr a c -- NB: the type of this function is the "shape" that GHC expects --- in tcInstClassOp. So don't put all the foralls at the front! +-- in tcInstClassOp. So don't put all the foralls at the front! -- Yes, this is a bit grotesque, but heck it works and the whole -- arrows stuff needs reworking anyway! f >>> g = g . f +{-# INLINE (>>>) #-} -- see Note [INLINE on >>>] in Control.Category -- A wrapper data type that lets the typechecker get at the appropriate dictionaries for an annotation data AnnotationWrapper = forall a. (Data a) => AnnotationWrapper a toAnnotationWrapper :: (Data a) => a -> AnnotationWrapper toAnnotationWrapper what = AnnotationWrapper what - ===================================== testsuite/tests/simplCore/should_compile/T18013.hs ===================================== @@ -0,0 +1,18 @@ +{-# OPTIONS_GHC -ddump-rule-firings -ddump-simpl + -dsuppress-coercions -dsuppress-uniques #-} +{-# LANGUAGE Arrows #-} + +module T18013 where + +import Control.Arrow +import T18013a + +-- We want to ensure this generates good code. Uses of (.) should be +-- specialized and inlined, and the rules defined on mkRule should fire. + +mapMaybeRule :: Rule IO a b -> Rule IO (Maybe a) (Maybe b) +mapMaybeRule f = proc v -> case v of + Just x -> do + y <- f -< x + returnA -< Just y + Nothing -> returnA -< Nothing ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -0,0 +1,210 @@ +Rule fired: Class op arr (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op arr (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op first (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Arrow (BUILTIN) +Rule fired: Class op arr (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op ||| (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: Class op . (BUILTIN) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op >>= (BUILTIN) +Rule fired: Class op pure (BUILTIN) +Rule fired: mkRule @(_, ()) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @((), _) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @((), _) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @(_, ()) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @((), _) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @((), _) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @(_, ()) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @((), _) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @(_, ()) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @(_, ()) (T18013a) +Rule fired: Class op fmap (BUILTIN) +Rule fired: mkRule @((), _) (T18013a) +Rule fired: Class op fmap (BUILTIN) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 52, types: 106, coercions: 15, joins: 0/1} + +-- RHS size: {terms: 37, types: 87, coercions: 15, joins: 0/1} +mapMaybeRule + :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 150 30}] +mapMaybeRule + = \ (@a) (@b) (f :: Rule IO a b) -> + case f of { Rule @s t0 g -> + let { + lvl :: Result s (Maybe b) + [LclId, Unf=OtherCon []] + lvl = T18013a.Result @s @(Maybe b) t0 (GHC.Maybe.Nothing @b) } in + T18013a.Rule + @IO + @(Maybe a) + @(Maybe b) + @s + t0 + ((\ (s2 :: s) + (a1 :: Maybe a) + (s1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case a1 of { + Nothing -> (# s1, lvl #); + Just x -> + case ((g s2 x) `cast` ) s1 of { (# ipv, ipv1 #) -> + case ipv1 of { Result t2 c1 -> + (# ipv, T18013a.Result @s @(Maybe b) t2 (GHC.Maybe.Just @b c1) #) + } + } + }) + `cast` ) + } + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18013.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18013.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18013.$trModule3 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18013.$trModule3 = GHC.Types.TrNameS T18013.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18013.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T18013.$trModule2 = "T18013"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18013.$trModule1 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18013.$trModule :: GHC.Types.Module +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T18013.$trModule + = GHC.Types.Module T18013.$trModule3 T18013.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/T18013a.hs ===================================== @@ -0,0 +1,58 @@ +{-# LANGUAGE BlockArguments, GADTs, LambdaCase #-} + +module T18013a where + +import Prelude hiding ((.), id) + +import Control.Category +import Control.Arrow +import Data.Functor + +data Result s a = Result !s a + +data Rule m a b where + Rule :: !s -> !(s -> a -> m (Result s b)) -> Rule m a b + +mkRule :: Functor m => s -> (s -> a -> m (Result s b)) -> Rule m a b +mkRule = Rule +{-# INLINE CONLIKE [1] mkRule #-} +{-# RULES +"mkRule @((), _)" forall s f. mkRule ((), s) f = + Rule s (\s1 a -> f ((), s1) a <&> \(Result ((), s2) b) -> Result s2 b) +"mkRule @(_, ())" forall s f. mkRule (s, ()) f = + Rule s (\s1 a -> f (s1, ()) a <&> \(Result (s2, ()) b) -> Result s2 b) +#-} + +instance Monad m => Category (Rule m) where + id = arr id + {-# INLINE id #-} + Rule t0 g . Rule s0 f = mkRule (s0, t0) \(s1, t1) a -> do + Result s2 b <- f s1 a + Result t2 c <- g t1 b + pure $! Result (s2, t2) c + {-# INLINE (.) #-} + +instance Monad m => Arrow (Rule m) where + arr f = Rule () \_ a -> pure $! Result () (f a) + {-# INLINE arr #-} + first (Rule s0 f) = Rule s0 \s1 (a, c) -> do + Result s2 b <- f s1 a + pure $! Result s2 (b, c) + {-# INLINE first #-} + +instance Monad m => ArrowChoice (Rule m) where + left (Rule s0 f) = Rule s0 \s1 -> \case + Left a -> do + Result s2 b <- f s1 a + pure $! Result s2 (Left b) + Right a -> + pure $! Result s0 (Right a) + {-# INLINE left #-} + Rule s0 f ||| Rule t0 g = mkRule (s0, t0) \(s1, t1) -> \case + Left a -> do + Result s2 b <- f s1 a + pure $! Result (s2, t0) b + Right a -> do + Result t2 b <- g t1 a + pure $! Result (s0, t2) b + {-# INLINE (|||) #-} ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -326,3 +326,4 @@ test('T17966', makefile_test, ['T17966']) # NB: T17810: -fspecialise-aggressively test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) +test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e8029816fda7602a8163c4d2703ff02982a3e48c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e8029816fda7602a8163c4d2703ff02982a3e48c You're receiving 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 12 21:16:11 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 12 Apr 2020 17:16:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17645-T17696 Message-ID: <5e93851b1e2d4_61673f8199536d9446092bc@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T17645-T17696 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17645-T17696 You're receiving 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 12 21:22:03 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Sun, 12 Apr 2020 17:22:03 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] 24 commits: rts: ProfHeap: Fix memory leak when not compiled with profiling Message-ID: <5e93867b7fbf3_6167134ebbc44613419@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 40881a2a by Sebastian Graf at 2020-04-12T23:20:51+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - 7c0ade24 by Sebastian Graf at 2020-04-12T23:21:53+02:00 Fix the perf regression in T12227/T12545 But now T9233 fails because we are doing more work. Temporarily marking as accepted increase. Metric Increase: T9233 Metric Decrease: hie002 - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcd81dbcb6a3368a4bba530930f583700c98c582...7c0ade24435fc29d2dbb4827f346a39147b55a97 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcd81dbcb6a3368a4bba530930f583700c98c582...7c0ade24435fc29d2dbb4827f346a39147b55a97 You're receiving 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 13 06:47:02 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 13 Apr 2020 02:47:02 -0400 Subject: [Git][ghc/ghc][wip/T16992] 19 commits: Make NoExtCon fields strict Message-ID: <5e940ae65451b_61677c82e0c4624197@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/T16992 at Glasgow Haskell Compiler / GHC Commits: 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - c00c81a5 by Ben Gamari at 2020-04-13T09:46:49+03:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 30 changed files: - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Foreign/Decl.hs - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/PmCheck.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/50276c01912a28eace285b7dd5f00572674ea9b5...c00c81a507d31b6d51e89f00d1e4c83f71c7d382 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/50276c01912a28eace285b7dd5f00572674ea9b5...c00c81a507d31b6d51e89f00d1e4c83f71c7d382 You're receiving 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 13 08:13:38 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 13 Apr 2020 04:13:38 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] Fix the perf regression in T12227/T12545 Message-ID: <5e941f3248fec_61673f8198ee100c463082b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: e4d8912e by Sebastian Graf at 2020-04-13T10:13:30+02:00 Fix the perf regression in T12227/T12545 But now T9233 fails because we are doing more work. Temporarily marking as accepted increase. Metric Increase: T9233 Metric Decrease: hie002 - - - - - 5 changed files: - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - utils/haddock Changes: ===================================== compiler/GHC/Core/Op/DmdAnal.hs ===================================== @@ -27,6 +27,7 @@ import Data.List ( mapAccumL ) import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Core.Arity ( typeArity ) import GHC.Core.Utils import GHC.Core.TyCon import GHC.Core.Type @@ -152,7 +153,7 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = (emptyDmdType conDiv, Lit lit) dmdAnal' _ _ (Type ty) = (emptyDmdType conDiv, Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = (unitDmdType (coercionDmdEnv co), Coercion co) + = (DmdType (coercionDmdEnv co) [] conDiv, Coercion co) dmdAnal' env dmd (Var var) = (dmdTransform env var dmd, Var var) @@ -410,7 +411,7 @@ forcesRealWorld fam_envs = go initRecTc -- search depth-first | Just DataConAppContext{ dcac_dc = dc, dcac_arg_tys = field_tys } <- deepSplitProductType_maybe fam_envs ty - -- don't check the same TyCon twice + -- don't check the same TyCon more than n times , Just rec_tc' <- checkRecTc rec_tc (dataConTyCon dc) = any (strict_field_forces rec_tc') field_tys | otherwise @@ -510,27 +511,63 @@ dmdTransform :: AnalEnv -- The strictness environment -- this function plus demand on its free variables dmdTransform env var dmd - | isDataConWorkId var -- Data constructor + -- Data constructors + | isDataConWorkId var = dmdTransformDataConSig (idArity var) dmd - + -- Dictionary component selectors | gopt Opt_DmdTxDictSel (ae_dflags env), - Just _ <- isClassOpId_maybe var -- Dictionary component selector + Just _ <- isClassOpId_maybe var = dmdTransformDictSelSig (idStrictness var) dmd - - | isGlobalId var -- Imported function - , let res = dmdTransformSig (idStrictness var) dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res]) + -- Imported functions + | isGlobalId var + , let res = dmdTransformSig (globalIdStrictness env var) dmd + = -- pprTrace "dmdTransform:import" (vcat [ppr var, ppr (idStrictness var), ppr (globalIdStrictness var), ppr dmd, ppr res]) res - - | Just (sig, top_lvl) <- lookupSigEnv env var -- Local letrec bound thing + -- Top-level or local let-bound thing for which we use LetDown ('useLetUp'). + -- In that case, we have a strictness signature to unleash in our AnalEnv. + | Just (sig, top_lvl) <- lookupSigEnv env var , let fn_ty = dmdTransformSig sig dmd - = -- pprTrace "dmdTransform" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ + = -- pprTrace "dmdTransform:LetDown" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl - then fn_ty -- Don't record top level things + then fn_ty -- Don't record demand on top-level things else addVarDmd fn_ty var (mkOnceUsedDmd dmd) - - | otherwise -- Local non-letrec-bound thing - = unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd)) + -- Everything else: + -- * Local let binders for which we use LetUp (cf. 'useLetUp') + -- * Lambda binders + -- * Case and constructor field binders + | let sig = mkConservativeSig env (idType var) + , let res = dmdTransformSig sig dmd + = -- pprTrace "dmdTransform:Other" (vcat [ppr var, ppr sig, ppr dmd, ppr res]) $ + addVarDmd res var (mkOnceUsedDmd dmd) + +-- | Returns 'idStrictness' or a conservative strictness signature for an +-- imported global variable for which 'idStrictness' is Top. +globalIdStrictness :: AnalEnv -> Id -> StrictSig +globalIdStrictness env var + | isTopSig (idStrictness var) = mkConservativeSig env (idType var) + | otherwise = idStrictness var + +mkConservativeSig :: AnalEnv -> Type -> StrictSig +mkConservativeSig env ty + -- Binders of unlifted types can't throw anything. This special case isn't + -- handled well by forcesRealWorld, which focuses on case scrutinees. + | unlifted = emptySig conDiv + -- no point in retaining cleared_sig when it's just Top + | no_change = topSig + | otherwise = cleared_sig + where + unlifted = isLiftedType_maybe ty == Just False + fam_envs = ae_fam_envs env + -- This is isomorphic to topSig. But this one has the right number of + -- arguments and will possibly have conDiv after the call to + -- tryClearPreciseException! + pessimistic_sig = StrictSig $ DmdType emptyVarEnv args topDiv + args = replicate (length (typeArity ty)) topDmd + -- In contrast to pessimistic_sig, cleared_sig might not have conDiv + -- Divergence! + cleared_sig = tryClearPreciseException fam_envs ty pessimistic_sig + sig_div = snd . splitStrictSig + no_change = sig_div cleared_sig == topDiv {- ************************************************************************ @@ -603,7 +640,7 @@ dmdFix top_lvl env let_dmd orig_pairs zapIdStrictness :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdStrictness pairs - = [(setIdStrictnessClearExn env id (emptySig topDiv), rhs) | (id, rhs) <- pairs ] + = [(setIdStrictnessClearExn env id topSig, rhs) | (id, rhs) <- pairs ] {- Note [Safe abortion in the fixed-point iteration] @@ -658,7 +695,7 @@ dmdAnalRhsLetDown rec_flag env let_dmd id rhs = mkRhsDmd env rhs_arity rhs (DmdType rhs_fv rhs_dmds rhs_div, rhs') = dmdAnal env rhs_dmd rhs - sig = mkStrictSigForArity rhs_arity (mkDmdType sig_fv rhs_dmds rhs_div) + sig = mkStrictSigForArity rhs_arity (DmdType sig_fv rhs_dmds rhs_div) id' = -- pprTraceWith "dmdAnalRhsLetDown" (\sig'-> ppr id <+> ppr sig <+> ppr sig') $ setIdStrictnessClearExn env id sig -- See Note [NOINLINE and strictness] @@ -944,9 +981,6 @@ deleted the special case. ************************************************************************ -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] conDiv - coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co) -- The VarSet from coVarsOfCo is really a VarEnv Var ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -23,8 +23,7 @@ module GHC.Types.Demand ( DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType, BothDmdArg, mkBothDmdArg, toBothDmdArg, - emptyDmdType, botDmdType, mkDmdType, addDemand, - mayThrowPreciseDmdType, + emptyDmdType, botDmdType, addDemand, mayThrowPreciseDmdType, DmdEnv, emptyDmdEnv, peelFV, findIdDemand, @@ -33,7 +32,7 @@ module GHC.Types.Demand ( topDiv, botDiv, exnDiv, conDiv, appIsDeadEnd, isDeadEndSig, pprIfaceStrictSig, StrictSig(..), mkStrictSigForArity, mkClosedStrictSig, - emptySig, botSig, cprProdSig, + emptySig, topSig, botSig, cprProdSig, isTopSig, hasDemandEnvSig, splitStrictSig, strictSigDmdEnv, prependArgsStrictSig, etaConvertStrictSig, @@ -1275,6 +1274,9 @@ emptyDmdType div = DmdType emptyDmdEnv [] div botDmdType :: DmdType botDmdType = emptyDmdType botDiv +topDmdType :: DmdType +topDmdType = emptyDmdType topDiv + isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env @@ -1284,9 +1286,6 @@ mayThrowPreciseDmdType (DmdType _ _ Dunno) = True mayThrowPreciseDmdType (DmdType _ _ ExnOrDiv) = True mayThrowPreciseDmdType _ = False -mkDmdType :: DmdEnv -> [Demand] -> Divergence -> DmdType -mkDmdType fv ds res = DmdType fv ds res - dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1788,6 +1787,9 @@ emptySig div = StrictSig (emptyDmdType div) botSig :: StrictSig botSig = StrictSig botDmdType +topSig :: StrictSig +topSig = StrictSig topDmdType + cprProdSig :: Arity -> StrictSig cprProdSig _arity = emptySig conDiv -- constructor applications never throw precise exceptions ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -658,7 +658,7 @@ setIdCprInfo :: Id -> CprSig -> Id setIdCprInfo id sig = modifyIdInfo (\info -> setCprInfo info sig) id zapIdStrictness :: Id -> Id -zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` emptySig topDiv) id +zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id -- | This predicate says whether the 'Id' has a strict demand placed on it or -- has a type such that it can always be evaluated strictly (i.e an ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -324,7 +324,7 @@ vanillaIdInfo inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, - strictnessInfo = emptySig topDiv, + strictnessInfo = topSig, cprInfo = topCprSig, callArityInfo = unknownArity, levityInfo = NoLevityInfo ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 65f22afa9e66195baa6b7d44369e2b23cd8f77d2 +Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e4d8912eb61de6e2d5de0b6a0b656526e1662705 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e4d8912eb61de6e2d5de0b6a0b656526e1662705 You're receiving 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 13 09:26:03 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 13 Apr 2020 05:26:03 -0400 Subject: [Git][ghc/ghc][wip/T17775] 18 commits: Don't override proc CafInfos in ticky builds Message-ID: <5e94302b19b99_616776d1c744631312@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - 14132e97 by Simon Peyton Jones at 2020-04-09T16:09:04+01:00 Simplify subsumption This patch implements GHC Proposal 287: Simplify subsumption and ticket #17775. The highlights are: * No deeplyInstantiate or deeplySkolemise * No tcSubTypeDS Everything else is a knock-on effect. I did a bit of renaming to make things consistent * tcPolyExpr becomes tcCheckPolyExpr ditto tcPolyExprNC * Add new function tcCheckMonoExpr e ty = tcMon0Expr expr (mkCheckExpType ty) and use it This all comopiles, but needs some eta-expansion in haskeline, and doubtless other packages. - - - - - 7feb5df9 by Simon Peyton Jones at 2020-04-09T16:13:14+01:00 Further refactoring and simplification Reviewed the main changes with Richard I had to do eta-expansion in a number of tests: T10283 T10390 T14488 T1634 T4284 T9569a T9834 tc145 tc160 tc208 tc210 twins - - - - - 548d8f22 by Ben Gamari at 2020-04-09T16:13:14+01:00 Bump haskeline submodule - - - - - e9c0333b by Simon Peyton Jones at 2020-04-09T16:13:18+01:00 Delete commented-out code - - - - - 4cbf8fc5 by Simon Peyton Jones at 2020-04-09T16:13:20+01:00 Fix (breaking) typo - - - - - 9a92286c by Simon Peyton Jones at 2020-04-09T16:13:22+01:00 Improve decomposition for FunTys This just improves error messages, avoiding Couldn't match type ‘Char’ with ‘Show a -> Char’ - - - - - c61810f6 by Ryan Scott at 2020-04-09T16:13:22+01:00 Bump Cabal submodule As well as some miscellaneous fixes needed to make GHC itself compile under simplified subsumption. - - - - - 279b173a by Simon Peyton Jones at 2020-04-09T16:15:51+01:00 Wibbles * Get expected/actual the right way round * Relevant-bindings fixes - - - - - 474331ac by Simon Peyton Jones at 2020-04-13T10:11:04+01:00 A lot more wibbles * Made String wired-in, so that "foo" :: String rather than "foo" :: [Char] * isTauTy: account for => * Bring dicts into scope when desugaring HsWrappers: addTyCsDs and hsWrapDictBinders * Improve reporting for occurs checks where skolems are involved e.g. 10715b, mc19, tcfail193, T13674, T4272, T3169, T7758, 7148 Payload is in the first case of mkTyVarEqErr * solveLocalEqualitesX: fail faster. we want to fail fast in T11142 Another example: T15629 And keep all equalities in dropMisleading. This gives better reporting in T12593 for example. * Move checkDataKindSig after the solveEqualities and zonk, obviously! * Move ic_telescope into ForAllSkol; a nice win. * Pretty-printing AbsBinds We are now very close to green - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.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/bd8eda7c22e8ccf88c2bf30de3edb69ba5519e2c...474331ace3eed36e398b76ce08c958fff3a9051d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bd8eda7c22e8ccf88c2bf30de3edb69ba5519e2c...474331ace3eed36e398b76ce08c958fff3a9051d You're receiving 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 13 10:10:04 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 13 Apr 2020 06:10:04 -0400 Subject: [Git][ghc/ghc][wip/T17775] A lot more wibbles Message-ID: <5e943a7c5c708_616776d1c7446388c@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 0d52887d by Simon Peyton Jones at 2020-04-13T11:09:39+01:00 A lot more wibbles * Made String wired-in, so that "foo" :: String rather than "foo" :: [Char] * isTauTy: account for => * Bring dicts into scope when desugaring HsWrappers: addTyCsDs and hsWrapDictBinders * Improve reporting for occurs checks where skolems are involved e.g. 10715b, mc19, tcfail193, T13674, T4272, T3169, T7758, 7148 Payload is in the first case of mkTyVarEqErr * solveLocalEqualitesX: fail faster. we want to fail fast in T11142 Another example: T15629 And keep all equalities in dropMisleading. This gives better reporting in T12593 for example. * Move checkDataKindSig after the solveEqualities and zonk, obviously! * Move ic_telescope into ForAllSkol; a nice win. * Pretty-printing AbsBinds We are now very close to green - - - - - 30 changed files: - compiler/GHC/Core/Type.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/prelude/PrelNames.hs - compiler/prelude/TysWiredIn.hs - ghc/GHCi/UI.hs - libraries/base/tests/T9681.stderr - testsuite/tests/ado/ado002.stderr - testsuite/tests/ado/ado004.stderr - testsuite/tests/annotations/should_fail/annfail06.hs - testsuite/tests/deSugar/should_compile/T10662.stderr - + testsuite/tests/dependent/should_compile/T15076c.stderr - testsuite/tests/dependent/should_compile/all.T - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/dependent/should_fail/BadTelescope5.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0d52887dc1e9f66fa8f48cd4d4817f8480f091f9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0d52887dc1e9f66fa8f48cd4d4817f8480f091f9 You're receiving 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 13 11:52:20 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 13 Apr 2020 07:52:20 -0400 Subject: [Git][ghc/ghc][wip/andreask/ticker_comments] 37 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e9452744ea0b_61677c82e0c465558c@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/ticker_comments at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 6b75e2c9 by Andreas Klebinger at 2020-04-13T07:52:16-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/796c42232a5e1fcdd34d885fa25d0749eb123661...6b75e2c959291bf320b0520c5fccf98322753388 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/796c42232a5e1fcdd34d885fa25d0749eb123661...6b75e2c959291bf320b0520c5fccf98322753388 You're receiving 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 13 13:34:24 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 13 Apr 2020 09:34:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/semigroup-sdoc Message-ID: <5e946a6041d82_616765c7a284657412@gitlab.haskell.org.mail> Vladislav Zavialov pushed new branch wip/semigroup-sdoc at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/semigroup-sdoc You're receiving 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 13 14:02:25 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 13 Apr 2020 10:02:25 -0400 Subject: [Git][ghc/ghc][wip/semigroup-sdoc] redundant import Message-ID: <5e9470f167283_61677c82e0c46629df@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/semigroup-sdoc at Glasgow Haskell Compiler / GHC Commits: f572e760 by Vladislav Zavialov at 2020-04-13T17:02:16+03:00 redundant import - - - - - 1 changed file: - compiler/GHC/Runtime/Linker/Types.hs Changes: ===================================== compiler/GHC/Runtime/Linker/Types.hs ===================================== @@ -15,7 +15,7 @@ module GHC.Runtime.Linker.Types ( SptEntry(..) ) where -import GhcPrelude ( FilePath, String, show, (<>) ) +import GhcPrelude ( FilePath, String, show ) import Data.Time ( UTCTime ) import Data.Maybe ( Maybe ) import Control.Concurrent.MVar ( MVar ) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f572e760a3dadb67cbc3b653c166c12bffb0db9f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f572e760a3dadb67cbc3b653c166c12bffb0db9f You're receiving 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 13 14:31:12 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Mon, 13 Apr 2020 10:31:12 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Add comments from SPJ. Message-ID: <5e9477b0ea8e1_616713503ee0467227a@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 197d2abd by Cale Gibbard at 2020-04-13T10:31:02-04:00 Add comments from SPJ. - - - - - 1 changed file: - compiler/GHC/Hs/Pat.hs Changes: ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -307,6 +307,7 @@ type instance XSigPat GhcTc = Type type instance XXPat GhcPs = NoExtCon type instance XXPat GhcRn = NoExtCon type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat type family ConLikeP x @@ -325,6 +326,8 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. data ConPatTc = ConPatTc { -- | The universal arg types 1-1 with the universal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/197d2abdd3e6f83e4b2f9b2f1006a0ac8e097658 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/197d2abdd3e6f83e4b2f9b2f1006a0ac8e097658 You're receiving 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 13 14:44:31 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Mon, 13 Apr 2020 10:44:31 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Add comment about Haddock's use of CollectPass Message-ID: <5e947acf69914_6167136dfb9c46792e3@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: cf9c3625 by Cale Gibbard at 2020-04-13T10:44:24-04:00 Add comment about Haddock's use of CollectPass - - - - - 1 changed file: - compiler/GHC/Hs/Utils.hs Changes: ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1161,9 +1161,12 @@ collect_pat pat bndrs = case pat of (SplicePat _ _) -> bndrs (XPat ext) -> collectXXPat (Proxy @p) ext bndrs --- This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. -- Consumers of the GHC API that define their own passes should feel free to implement instances in order -- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. class (XRec p Pat ~ Located (Pat p)) => CollectPass p where collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf9c3625a5c2b3086b945f025ae42eb2aff757fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf9c3625a5c2b3086b945f025ae42eb2aff757fd You're receiving 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 13 14:48:38 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Mon, 13 Apr 2020 10:48:38 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Add comment about haddock's use of CollectPass. Message-ID: <5e947bc625622_61677c82e0c4680225@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 7e3e5d90 by Cale Gibbard at 2020-04-13T10:48:19-04:00 Add comment about haddock's use of CollectPass. - - - - - 1 changed file: - compiler/GHC/Hs/Utils.hs Changes: ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1161,9 +1161,12 @@ collect_pat pat bndrs = case pat of (SplicePat _ _) -> bndrs (XPat ext) -> collectXXPat (Proxy @p) ext bndrs --- This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. -- Consumers of the GHC API that define their own passes should feel free to implement instances in order -- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. class (XRec p Pat ~ Located (Pat p)) => CollectPass p where collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e3e5d90d6302996ff898fc4585a7aa162268eaf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e3e5d90d6302996ff898fc4585a7aa162268eaf You're receiving 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 13 14:51:19 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Mon, 13 Apr 2020 10:51:19 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 4 commits: Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e947c67b3822_6167e4e49b446810fb@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: c8803c9d by John Ericson at 2020-04-13T10:49:31-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. - - - - - 676ae2d8 by Cale Gibbard at 2020-04-13T10:49:31-04:00 Pure refactor of code around ConPat Now that things are working, clean some things up: - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently - - - - - a664011a by Cale Gibbard at 2020-04-13T10:49:31-04:00 Fix T6145 (ConPatIn became ConPat) - - - - - c2e3d080 by Cale Gibbard at 2020-04-13T10:50:42-04:00 Add comments from SPJ. Add comment about haddock's use of CollectPass. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Types.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - compiler/typecheck/TcArrows.hs - compiler/typecheck/TcBinds.hs - compiler/typecheck/TcGenDeriv.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcPat.hs - compiler/typecheck/TcPatSyn.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/typecheck/TcTyDecls.hs - compiler/typecheck/TcValidity.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -23,8 +23,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +62,6 @@ import TcEvidence import BasicTypes -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import Var import RdrName ( RdrName ) @@ -71,12 +73,10 @@ import GHC.Core.Type import SrcLoc import Bag -- collect ev vars from pats import Maybes +import Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +173,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +244,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat (XXPat p) @@ -306,6 +277,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +304,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +326,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +526,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +562,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,23 +577,35 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in TcBinds.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details -pprPat (XPat n) = noExtCon n - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -603,21 +644,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -685,7 +729,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -701,13 +745,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -717,18 +762,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -737,7 +783,11 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False - go (XPat {}) = False + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go pat + where CoPat _ pat _ = ext -- | Is the pattern any of combination of: -- @@ -780,16 +830,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -801,7 +856,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -814,7 +868,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -840,12 +897,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -133,6 +137,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -195,8 +200,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -229,7 +237,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -434,25 +442,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -795,11 +820,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -874,8 +899,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -884,6 +911,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -973,7 +1001,8 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here @@ -981,42 +1010,61 @@ collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] collectLocalBinders (XHsLocalBindsLR _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1040,19 +1088,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1072,44 +1124,61 @@ collectStmtBinders (XStmtLR nec) = noExtCon nec ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1410,10 +1479,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1196,7 +1196,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1236,8 +1236,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1245,10 +1245,9 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) - go p@(XPat {}) = pprPanic "collectl/go" (ppr p) collectEvBinders :: TcEvBinds -> [Id] collectEvBinders (EvBinds bs) = foldr add_ev_bndr [] bs ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -705,13 +705,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -270,7 +270,7 @@ deListComp (ApplicativeStmt {} : _) _ = deListComp (XStmtLR nec : _) _ = noExtCon nec -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1120,8 +1123,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1138,7 +1142,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -444,7 +444,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -499,11 +499,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -545,9 +548,7 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" - XPat n -> noExtCon n -- | 'translatePat', but also select and return a new match var. translatePatV :: FamInstEnvs -> Pat GhcTc -> DsM (Id, GrdVec) ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1984,7 +1984,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -769,6 +769,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -811,12 +812,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -840,9 +840,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] - XPat _ -> [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1847,8 +1848,7 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -517,7 +517,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +534,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Rename/Types.hs ===================================== @@ -1231,28 +1231,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1281,7 +1300,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) checkPrecMatch _ (XMatchGroup nec) = noExtCon nec checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1270,12 +1270,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1288,8 +1298,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1319,7 +1333,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -603,7 +603,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1077,7 +1077,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1114,7 +1118,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2065,7 +2073,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== compiler/typecheck/TcArrows.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/typecheck/TcBinds.hs ===================================== @@ -505,8 +505,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/typecheck/TcGenDeriv.hs ===================================== @@ -533,9 +533,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/typecheck/TcHsSyn.hs ===================================== @@ -116,15 +116,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType (XPat n) = noExtCon n -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1308,7 +1309,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1370,13 +1371,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1396,12 +1400,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1432,19 +1443,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1463,7 +1475,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/typecheck/TcPat.hs ===================================== @@ -495,7 +495,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -786,12 +786,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -820,13 +823,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -871,13 +878,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/typecheck/TcPatSyn.hs ===================================== @@ -942,7 +942,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -975,8 +975,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1128,10 +1126,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/typecheck/TcTyClsDecls.hs ===================================== @@ -2195,9 +2195,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2234,8 +2234,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/typecheck/TcTyDecls.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/typecheck/TcValidity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 3174ad334c2c505394703ce96fcb67ace94a427c +Subproject commit 6809c3cc93193c049f296510a1561941b0a92a5e View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7e3e5d90d6302996ff898fc4585a7aa162268eaf...c2e3d0807c6045c41a4cd82128df01378c512d58 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7e3e5d90d6302996ff898fc4585a7aa162268eaf...c2e3d0807c6045c41a4cd82128df01378c512d58 You're receiving 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 13 15:34:40 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 13 Apr 2020 11:34:40 -0400 Subject: [Git][ghc/ghc][wip/T17645-T17696] Bump template-haskell version to 2.17.0.0 Message-ID: <5e948690a8905_616765c7a2847084fc@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T17645-T17696 at Glasgow Haskell Compiler / GHC Commits: 4b6589e2 by Ryan Scott at 2020-04-13T11:33:21-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc.mk - libraries/exceptions - libraries/ghci/ghci.cabal.in - libraries/template-haskell/template-haskell.cabal.in - libraries/text - utils/ghc-cabal/ghc.mk Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -69,7 +69,7 @@ Library containers >= 0.5 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, - template-haskell == 2.16.*, + template-haskell == 2.17.*, hpc == 0.6.*, transformers == 0.5.*, ghc-boot == @ProjectVersionMunged@, ===================================== ghc.mk ===================================== @@ -413,8 +413,8 @@ else # CLEANING # Packages that are built by stage0. These packages are dependencies of # programs such as GHC and ghc-pkg, that we do not assume the stage0 # compiler already has installed (or up-to-date enough). - -PACKAGES_STAGE0 = binary text transformers mtl parsec Cabal/Cabal hpc ghc-boot-th ghc-boot template-haskell ghc-heap ghci +# Note that these must be given in topological order. +PACKAGES_STAGE0 = binary transformers mtl hpc ghc-boot-th ghc-boot template-haskell text parsec Cabal/Cabal ghc-heap ghci ifeq "$(Windows_Host)" "NO" PACKAGES_STAGE0 += terminfo endif @@ -441,14 +441,14 @@ PACKAGES_STAGE1 += process PACKAGES_STAGE1 += hpc PACKAGES_STAGE1 += pretty PACKAGES_STAGE1 += binary -PACKAGES_STAGE1 += text PACKAGES_STAGE1 += transformers PACKAGES_STAGE1 += mtl -PACKAGES_STAGE1 += parsec -PACKAGES_STAGE1 += Cabal/Cabal PACKAGES_STAGE1 += ghc-boot-th PACKAGES_STAGE1 += ghc-boot PACKAGES_STAGE1 += template-haskell +PACKAGES_STAGE1 += text +PACKAGES_STAGE1 += parsec +PACKAGES_STAGE1 += Cabal/Cabal PACKAGES_STAGE1 += ghc-compact PACKAGES_STAGE1 += ghc-heap ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit 0a1f9ff0f407da360fc9405a07d5d06d28e6c077 +Subproject commit fe4166f8d23d8288ef2cbbf9e36118b6b99e0d7d ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -81,7 +81,7 @@ library ghc-boot == @ProjectVersionMunged@, ghc-boot-th == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.16.*, + template-haskell == 2.17.*, transformers == 0.5.* if !os(windows) ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -3,7 +3,7 @@ -- template-haskell.cabal. name: template-haskell -version: 2.16.0.0 +version: 2.17.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit 1127b30e1e0affa08f056e35ad17957b12982ba3 +Subproject commit a01843250166b5559936ba5eb81f7873e709587a ===================================== utils/ghc-cabal/ghc.mk ===================================== @@ -23,9 +23,9 @@ CABAL_CONSTRAINT := --constraint="Cabal == $(CABAL_DOTTED_VERSION)" # macros is triggered by `-hide-all-packages`, so we have to explicitly # enumerate all packages we need in scope. ifeq "$(Windows_Host)" "YES" -CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath Win32 +CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath Win32 template-haskell else -CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath unix +CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath unix template-haskell endif ghc-cabal_DIST_BINARY_NAME = ghc-cabal$(exeext0) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b6589e21b100672fcef3b067deaf71ef2fc83bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b6589e21b100672fcef3b067deaf71ef2fc83bd You're receiving 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 13 15:37:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 11:37:48 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5e94874c49585_61673f81ef22dee447114e6@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: 268aee74 by Ben Gamari at 2020-04-13T11:37:38-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 10 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +flushEventLog :: IO () +flushEventLog = c_flushEventLog nullPtr + +foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO () ===================================== rts/Capability.c ===================================== @@ -23,6 +23,7 @@ #include "Schedule.h" #include "Sparks.h" #include "Trace.h" +#include "EventLog.h" // for flushLocalEventsBuf #include "sm/GC.h" // for gcWorkerThread() #include "STM.h" #include "RtsUtils.h" @@ -885,6 +886,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushTrace(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/Trace.h ===================================== @@ -319,7 +319,6 @@ void traceConcSweepEnd(void); void traceConcUpdRemSetFlush(Capability *cap); void traceNonmovingHeapCensus(uint32_t log_blk_size, const struct NonmovingAllocCensus *census); - void flushTrace(void); #else /* !TRACING */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -16,6 +16,7 @@ #include "RtsUtils.h" #include "Stats.h" #include "EventLog.h" +#include "Schedule.h" #include #include @@ -271,7 +272,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1566,26 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = myTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) @@ -1578,4 +1599,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { void endEventLogging(void) {} +void flushEventLog(Capability **cap STG_UNUSED) {} + #endif /* TRACING */ ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,10 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event @@ -175,6 +177,9 @@ void postNonmovingHeapCensus(int log_blk_size, #else /* !TRACING */ +INLINE_HEADER void flushLocalEventsBuf(Capability *cap) +{ /* nothing */ } + INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, EventTypeNum tag STG_UNUSED, StgThreadID id STG_UNUSED, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/268aee74c8e2f457ae2f7f86b875ede84d8a40bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/268aee74c8e2f457ae2f7f86b875ede84d8a40bd You're receiving 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 13 15:44:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 11:44:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18037 Message-ID: <5e9488dc5eb4_61673f81ef22dee4471344d@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18037 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18037 You're receiving 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 13 15:51:27 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 13 Apr 2020 11:51:27 -0400 Subject: [Git][ghc/ghc][wip/semigroup-sdoc] Use Semigroup's (<>) for Doc/SDoc Message-ID: <5e948a7f23d3c_6167e4e49b447150b0@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/semigroup-sdoc at Glasgow Haskell Compiler / GHC Commits: e4cf1c5d by Vladislav Zavialov at 2020-04-13T18:51:18+03:00 Use Semigroup's (<>) for Doc/SDoc Before this patch, Outputable.hs defined its own (<>) which caused conflicts with (Data.Semigroup.<>) and thus led to inconvenience. However, replacing it is not trivial due to a different fixity: http://www.haskell.org/pipermail/libraries/2011-November/017066.html Nevertheless, it is possible to update the pretty-printing code to work with (<>) of a different fixitiy, and that's what this patch implements. Now Doc and SDoc are instances of Semigroup. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Instance/FunDeps.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Var/Set.hs - compiler/main/Ar.hs - compiler/parser/RdrHsSyn.hs - compiler/utils/GhcPrelude.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e4cf1c5db6135dec71929358f9012d385a7441c1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e4cf1c5db6135dec71929358f9012d385a7441c1 You're receiving 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 13 16:00:35 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 12:00:35 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] 1569 commits: Explain that 'mappend' and '(<>)' should be the same [skip ci] Message-ID: <5e948ca39d4b9_6167136dfb9c4716812@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: 0462b0e0 by Alexandre Baldé at 2019-06-09T11:48:34-04:00 Explain that 'mappend' and '(<>)' should be the same [skip ci] - - - - - 970e4802 by Matthew Pickering at 2019-06-09T11:49:09-04:00 hadrian: Properly partition options in sourceArgs Previously if you build the `ghc` package then it would has the default opts and the library opts. This is different behaviour to make where the library opts are only reserved for things in the `libraries` subdirectory (I believe) Fixes #16716 - - - - - a018c3a8 by Ben Gamari at 2019-06-09T11:49:44-04:00 testsuite: Suppress ticks in T4918 output As noted in #16741, this test otherwise breaks when `base` is compiled with `-g`. - - - - - f7370333 by chessai at 2019-06-09T18:41:02-04:00 Introduce log1p and expm1 primops Previously log and exp were primitives yet log1p and expm1 were FFI calls. Fix this non-uniformity. - - - - - 41bf4045 by Ben Gamari at 2019-06-09T18:41:38-04:00 testsuite: Add test for #16514 - - - - - b9fe91fc by Simon Jakobi at 2019-06-09T18:42:21-04:00 Small refactorings in ExtractDocs - - - - - 9d238791 by Kevin Buhr at 2019-06-09T18:42:57-04:00 Handle trailing path separator in package DB names (#16360) Package DB directories with trailing separator (provided via GHC_PACKAGE_PATH or via -package-db) resulted in incorrect calculation of ${pkgroot} substitution variable. Keep the trailing separator while resolving as directory or file, but remove it before dropping the last path component with takeDirectory. Closes #16360. - - - - - a22e51ea by Richard Eisenberg at 2019-06-09T18:43:38-04:00 Fix #16517 by bumping the TcLevel for method sigs There were actually two bugs fixed here: 1. candidateQTyVarsOfType needs to be careful that it does not try to zap metavariables from an outer scope as "naughty" quantification candidates. This commit adds a simple check to avoid doing so. 2. We weren't bumping the TcLevel in kcHsKindSig, which was used only for class method sigs. This mistake led to the acceptance of class C a where meth :: forall k. Proxy (a :: k) -> () Note that k is *locally* quantified. This patch fixes the problem by using tcClassSigType, which correctly bumps the level. It's a bit inefficient because tcClassSigType does other work, too, but it would be tedious to repeat much of the code there with only a few changes. This version works well and is simple. And, while updating comments, etc., I noticed that tcRnType was missing a pushTcLevel, leading to #16767, which this patch also fixes, by bumping the level. In the refactoring here, I also use solveEqualities. This initially failed ghci/scripts/T15415, but that was fixed by teaching solveEqualities to respect -XPartialTypeSignatures. This patch also cleans up some Notes around error generation that came up in conversation. Test case: typecheck/should_fail/T16517, ghci/scripts/T16767 - - - - - 10452959 by Roland Senn at 2019-06-09T18:44:18-04:00 Add disable/enable commands to ghci debugger #2215 This patch adds two new commands `:enable` and `:disable` to the GHCi debugger. Opposite to `:set stop <n> :continue` a breakpoint disabled with `:disable` will not loose its previously set stop command. A new field breakEnabled is added to the BreakLocation data structure to track the enable/disable state. When a breakpoint is disabled with a `:disable` command, the following happens: The corresponding BreakLocation data element is searched dictionary of the `breaks` field of the GHCiStateMonad. If the break point is found and not already in the disabled state, the breakpoint is removed from bytecode. The BreakLocation data structure is kept in the breaks list and the new breakEnabled field is set to false. The `:enable` command works similar. The breaks field in the GHCiStateMonad was changed from an association list to int `IntMap`. - - - - - 13572480 by Ben Gamari at 2019-06-09T18:44:54-04:00 rts: Separate population of eventTypes from initial event generation Previously these two orthogonal concerns were both implemented in postHeaderEvents which made it difficult to send header events after RTS initialization. - - - - - ed20412a by nineonine at 2019-06-09T18:45:31-04:00 Do not report error if Name in pragma is unbound - - - - - 8a48a8a4 by Ben Gamari at 2019-06-09T18:46:08-04:00 testsuite: Add test for #16509 - - - - - 69c58f8a by David Eichmann at 2019-06-09T18:46:46-04:00 Hadrian: need CPP preprocessor dependencies #16660 Use the new -include-cpp-deps ghc option (#16521) when generating .dependencies files in hadrian. This is version gated as -include-cpp-deps is a relatively new option. - - - - - 1c7bb03d by Richard Eisenberg at 2019-06-09T18:47:24-04:00 Comments only: document tcdDataCusk better. - - - - - 5023adce by John Ericson at 2019-06-09T18:47:59-04:00 Remove CPP ensuring word size is 32 or 64 bits around Addr# <-> int# primops It shouldn't be needed these days, and those primops are "highly deprecated" anyways. This fits with my plans because it removes one bit of target-dependence of the builtin primops, and this is the hardest part of GHC to make multi-target. CC @carter - - - - - 8e60e3f0 by Daniel Gröber at 2019-06-09T18:48:38-04:00 rts: Fix RetainerProfile early return with TREC_CHUNK When pop() returns with `*c == NULL` retainerProfile will immediately return. All other code paths is pop() continue with the next stackElement when this happens so it seems weird to me that TREC_CHUNK we would suddenly abort everything even though the stack might still have elements left to process. - - - - - 1a3420ca by Ben Gamari at 2019-06-10T07:59:41-04:00 base: Mark CPUTime001 as fragile As noted in #16224, CPUTime001 has been quite problematic, reporting non-monotonic timestamps in CI. Unfortunately I've been unable to reproduce this locally. - - - - - 9bc10993 by Vladislav Zavialov at 2019-06-10T08:00:16-04:00 Print role annotations in TemplateHaskell brackets (#16718) - - - - - 0345b1b0 by Richard Eisenberg at 2019-06-10T23:52:10-04:00 Comments only: document newtypes' DataConWrapId - - - - - 58a5d728 by David Eichmann at 2019-06-10T23:52:50-04:00 Refactor the rules for .hi and .o into a single rule using `&%>` #16764 Currently the rule for .hi files just triggers (via need) the rule for the .o file, and .o rule generates both the .o and .hi file. Likewise for .o-boot and .hi-boot files. This is a bit of an abuse of Shake, and in fact shake supports rules with multiple output with the &%> function. This exact use case appears in Neil Mitchell's paper *Shake Before Building* section 6.3. - - - - - 2f945086 by Ben Gamari at 2019-06-10T23:53:25-04:00 testsuite: Fix and extend closure_size test This was previously broken in several ways. This is fixed and it also now tests arrays. Unfortunately I was unable to find a way to continue testing PAP and FUN sizes; these simply depend too much upon the behavior of the simplifier. I also tried to extend this to test non-empty arrays as well but unfortunately this was non-trivial as the array card size constant isn't readily available from haskell. Fixes #16531. - - - - - e5d275f4 by Ben Gamari at 2019-06-10T23:53:25-04:00 ghc-heap: Add closure_size_noopt test This adds a new test, only run in the `normal` way, to verify the size of FUNs and PAPs. - - - - - fe7e7e4a by Yuras Shumovich at 2019-06-11T18:39:58-04:00 Warn about unused packages Reviewers: bgamari, simonpj Reviewed By: simonpj Subscribers: hvr, simonpj, mpickering, rwbarton, carter GHC Trac Issues: #15838 Differential Revision: https://phabricator.haskell.org/D5285 - - - - - 39f50bff by Alp Mestanogullari at 2019-06-11T18:40:37-04:00 Refine the GHCI macro into HAVE[_{INTERNAL, EXTERNAL}]_INTERPRETER As discussed in #16331, the GHCI macro, defined through 'ghci' flags in ghc.cabal.in, ghc-bin.cabal.in and ghci.cabal.in, is supposed to indicate whether GHC is built with support for an internal interpreter, that runs in the same process. It is however overloaded in a few places to mean "there is an interpreter available", regardless of whether it's an internal or external interpreter. For the sake of clarity and with the hope of more easily being able to build stage 1 GHCs with external interpreter support, this patch splits the previous GHCI macro into 3 different ones: - HAVE_INTERNAL_INTERPRETER: GHC is built with an internal interpreter - HAVE_EXTERNAL_INTERPRETER: GHC is built with support for external interpreters - HAVE_INTERPRETER: HAVE_INTERNAL_INTERPRETER || HAVE_EXTERNAL_INTERPRETER - - - - - 45616133 by Alec Theriault at 2019-06-11T18:41:14-04:00 Make `haddock_testsuite` respect `--test-accept` Suppose you've made changes that affect the output of `haddockHtmlTest` so that the following is failing: ./hadrian/build.sh -c --only=haddockHtmlTest test Then, the following will accept new output for Haddock's test cases. ./hadrian/build.sh -c --only=haddockHtmlTest test --test-accept You still do need to make sure those new changes (which show up in Haddock's tree) get committed though. Fixes #16694 - - - - - 762098bf by Alp Mestanogullari at 2019-06-11T18:41:52-04:00 rts/RtsFlags.c: mention that -prof too enables support for +RTS -l - - - - - 457fe789 by Alp Mestanogullari at 2019-06-11T18:42:30-04:00 Hadrian: teach the RTS that PROFILING implies TRACING As discussed in #16744, both the Make and Hadrian build systems have special code to always pass -eventlog whenever -prof or -debug are passed. However, there is some similar logic in the RTS itself only for defining TRACING when the DEBUG macro is defined, but no such logic is implemented to define TRACING when the PROFILING macro is defined. This patch adds such a logic and therefore fixes #16744. - - - - - cf7f36ae by Ben Gamari at 2019-06-11T18:43:05-04:00 rts/linker: Mmap into low memory on AArch64 This extends mmapForLinker to use the same low-memory mapping strategy used on x86_64 on AArch64. See #16784. - - - - - 0b7f81f5 by Ben Gamari at 2019-06-11T18:43:05-04:00 rts/linker: Use mmapForLinker to map PLT The PLT needs to be located within a close distance of the code calling it under the small memory model. Fixes #16784. - - - - - 1389b2cc by Ömer Sinan Ağacan at 2019-06-11T18:43:43-04:00 Fix an error message in CheckUnload.c:searchHeapBlocks - - - - - aad6115a by Alp Mestanogullari at 2019-06-11T18:44:20-04:00 testsuite/mk/boilerplate.mk: rename 'ghc-config-mk' to 'ghc_config_mk' Make/shell variable names which contain dashes can cause problems under some conditions. The 'ghc-config-mk' variable from testsuite/mk/boilerplate.mk that I made overridable (by Hadrian) in ba0aed2e was working as expected when our Hadrian/Linux job was based off the deb8 Docker image, but broke when I switched the job to use our deb9-based image, in 3d97bad6. The exact circumstances/tool versions that trigger this problem are unknown, but changing the variable's name to 'ghc_config_mk' lets us work around the issue. This fixes the annth_compunits and annth_make test failures that showed up when we switched the Hadrian/Linux job to use the deb9 environment. - - - - - 9b4ff57d by Ben Gamari at 2019-06-12T07:35:25-04:00 llvm-targets: Add armv7l-unknown-linux-gnueabi Fixes #15208. [skip ci] - - - - - c05ca251 by Ben Gamari at 2019-06-12T07:36:01-04:00 testsuite: Add haddock perf test output to gitignore [skip ci] - - - - - bbc752c5 by Ben Gamari at 2019-06-12T07:36:36-04:00 rts/linker: Make elf_got.c a bit more legible - - - - - 217e6db4 by Ben Gamari at 2019-06-12T07:36:36-04:00 rts/linker: Only mprotect GOT after it is filled This fixes a regression, introduced by 67c422ca, where we mprotect'd the global offset table (GOT) region to PROT_READ before we had finished filling it, resulting in a linker crash. Fixes #16779. - - - - - 1219f8e8 by Krzysztof Gogolewski at 2019-06-12T07:37:12-04:00 Use DeriveFunctor throughout the codebase (#15654) - - - - - bd2d13ff by Ben Gamari at 2019-06-12T08:19:59-04:00 Bump binary to 0.8.7.0 (cherry picked from commit 983ada70a013c7642a751f6e41587ff95b57d0f8) - - - - - 381c3ae3 by Ben Gamari at 2019-06-12T08:19:59-04:00 Bump Cabal submodule (cherry picked from commit ff438786613f07df9b2d43eaeac49b13815d849d) Metric Increase: haddock.Cabal - - - - - 0354c7de by Ben Gamari at 2019-06-12T08:19:59-04:00 Bump time submodule to 1.9.3 (cherry picked from commit fdb07571036b1498800589d45b61781e6acdd368) - - - - - e0b16eaa by Ben Gamari at 2019-06-12T08:19:59-04:00 Bump terminfo to 0.4.1.4 (cherry picked from commit 1134488b4c9cef904ea82f22f1978646eea612df) - - - - - 2ce320b0 by Ben Gamari at 2019-06-12T08:19:59-04:00 gitlab-ci: Test using slowtest in deb9-debug job - - - - - 90e7c450 by Ben Gamari at 2019-06-12T08:19:59-04:00 testsuite: Mark hWaitForInput-accurate-stdin as broken in threaded ways As noted in #16535. - - - - - 488187f8 by Ben Gamari at 2019-06-12T08:19:59-04:00 testsuite: Mark T13167 as fragile in threaded2 As noted in #16536. - - - - - 9b583320 by Ben Gamari at 2019-06-12T08:19:59-04:00 testsuite: Mark T13910 as broken in optasm Due to #16537. - - - - - eb644865 by Ben Gamari at 2019-06-12T08:19:59-04:00 testsuite: Mark T14761c as broken in hpc, profasm, and optasm ways As noted in #16540. - - - - - 1a204e07 by Ben Gamari at 2019-06-12T08:19:59-04:00 testsuite: Mark T16180 as broken in ghci and ext-interp ways As noted in #16541. - - - - - 8d482e45 by Ben Gamari at 2019-06-12T08:19:59-04:00 testsuite: Omit tcrun022 in hpc way As noted in #16542, the expected rule doesn't fire. However, this doesn't seem terribly surpring given the circumstances. - - - - - 68cfdfdb by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Mark Overflow as broken in hpc way As noted in #16543. - - - - - a3929a4f by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Mark T2783 as fragile in threaded1 It was previously marked as broken but it passes non-deterministically. See #2783. - - - - - bb7ed32f by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Skip T7919 in ghci way It times out pretty reliably. It's not clear that much is gained by running this test in the ghci way anyways. - - - - - 329dcd7a by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Fix fragile_for test modifier - - - - - 55b5bb14 by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Fix omit_ways usage omit_ways expects a list but this was broken in several cases. - - - - - 264ad286 by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Mark threadstatus-T9333 as fragile in ghci way As noted in #16555. - - - - - 587bef66 by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Omit profasm way for cc017 cc017 requires TH but we can't load dynamic profiled objects. - - - - - dc5a37fd by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Skip T493 in ghci way. T493 tests #493, which is an FFI test. FFI tests should be skipped in ghci way. - - - - - e3f71d0e by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Mark T16449_2 as broken due to #16742 - - - - - b5a13a1e by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Mark T16737 as broken in ghci way due to #16541 - - - - - b09374a4 by Ben Gamari at 2019-06-12T08:20:25-04:00 testsuite: Note intentional typo in T7130 I earlier accidentally corrected it breaking the test. - - - - - a798c130 by Ben Gamari at 2019-06-12T08:20:25-04:00 linters/check-makefiles: Limit lint to Makefiles Previously we would apply this rule, which is only intended for testsuite Makefiles, to all files. This lead to a number of false-positives in all.T files. - - - - - 0782141e by Ben Gamari at 2019-06-12T08:20:25-04:00 gitlab-ci: Fetch submodules before running submodule linter - - - - - 898f7e92 by Ben Gamari at 2019-06-12T08:20:25-04:00 Fix uses of #ifdef/#ifndef The linter now enforces our preference for `#if defined()` and `#if !defined()`. - - - - - 0a13a04c by Ben Gamari at 2019-06-12T08:20:25-04:00 Bump unix submodule Marks posix002 as fragile in threaded2 way due to #16550. - - - - - a8579e5b by Ben Gamari at 2019-06-12T08:27:25-04:00 process: Bump submodule * Skip process005 in ghci way * Mark process002 as fragile in threaded2 - - - - - 3f1022c5 by Ben Gamari at 2019-06-12T08:27:25-04:00 testsuite: Skip cgrun078 in ghci way This test requires FFI usage. - - - - - 1cbfef47 by Ben Gamari at 2019-06-12T08:27:25-04:00 testsuite: Unbreak galois_raytrace on i386 galois_raytrace was previously broken on i386 due to use of x87 arithmethic on that platform. However, 42504f4a575395a35eec5c3fd7c9ef6e2b54e68e removes x87 support; this resulted in an unexpected pass. Unmark this test as broken. - - - - - 20160f1a by Ben Gamari at 2019-06-12T08:27:25-04:00 testsuite: Don't run tests requiring TH in profasm way when GhcDynamic Since we can't load profiled objects when GhcDynamic==YES. Affects: * T16737 * T16384 * T16718 * T16619 * T16190 - - - - - 7b751ed8 by Ben Gamari at 2019-06-12T17:52:35-04:00 gitlab-ci: Bump Docker image Fixes linters. - - - - - 5ffc266e by Ben Gamari at 2019-06-13T02:48:13-04:00 Add a few missing llvm-targets This should finally fix #14261. [skip ci] - - - - - fc6b23be by Phuong Trinh at 2019-06-13T02:48:50-04:00 Fix #16525: ObjectCode freed wrongly because of lack of info header check `checkUnload` currently doesn't check the info header of static objects. Thus, it may free an `ObjectCode` struct wrongly even if there's still a live static object whose info header lies in a mapped section of that `ObjectCode`. This fixes the issue by adding an appropriate check. - - - - - a657543c by Ben Gamari at 2019-06-13T02:49:25-04:00 PrelRules: Ensure that string unpack/append rule fires with source notes Previously the presence of source notes could hide nested applications of `unpackFoldrCString#` from our constant folding logic. For instance, consider the expression: ```haskell unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) ``` Specifically, ticks appearing in two places can defeat the rule: a. Surrounding the inner application of `unpackFoldrCString#` b. Surrounding the fold function, `c` The latter caused the `str_rules` testcase to fail when `base` was built with `-g3`. Fixes #16740. - - - - - e98d32a6 by David Eichmann at 2019-06-13T02:50:00-04:00 Hadrian: Track RTS library symlink targets This requires creating RTS library symlinks when registering, outside of the rule for the registered library file. - - - - - 35113117 by Alp Mestanogullari at 2019-06-13T02:50:37-04:00 Hadrian: Do not allow the Linux jobs to fail anymore MR !1151 makes the Hadrian/Linux job pass by fixing the last two test failures, so we can now be stricter and not allow those jobs to fail anymore, easily letting us see when patches introduce test failures. - - - - - 70b5eefe by Ben Gamari at 2019-06-13T02:51:13-04:00 users-guide: Fix a few markup issues Strangely these were only causing the build to fail in the aarch64-linux job, despite Sphinx throwing errors in all jobs I checked. Also changes some `#ifdef`s to `#if defined` to satisfy the linter. - - - - - 9721b40d by Ben Gamari at 2019-06-13T02:51:13-04:00 gitlab-ci: Don't build PDF user's guide on AArch64 For reasons I don't understand sphinx seems to fail to produce a .idx file for makeindex. - - - - - d550b771 by Ben Gamari at 2019-06-13T02:51:50-04:00 Clean up .circleci Move prepare-system.sh to .gitlab and remove everything else. - - - - - c53dfb3b by Ben Gamari at 2019-06-13T11:52:47-04:00 testsuite: A more portable solution to #9399 Previously we used an awful hybrid batch script/Bourne shell script to allow this test to run both on Windows and Linux (fixing #9399). However, this breaks on some libc implementations (e.g. musl). Fix this. Fixes #16798. - - - - - 74b5d049 by Ben Gamari at 2019-06-13T11:53:22-04:00 gitlab-ci: Disable deb9-llvm job, introduce nightly LLVM job This should help alleviate queue times as the LLVM job is one of the longest that we have. - - - - - 5ce63d52 by Ben Gamari at 2019-06-13T11:53:22-04:00 gitlab-ci: Disable validate-x86_64-linux-deb9 job to reduce load Enable artifacts on to ensure we have bindist coverage. - - - - - 7bc5d6c6 by Ben Gamari at 2019-06-13T23:34:41-04:00 Maintain separate flags for C++ compiler invocations Previously we would pass flags intended for the C compiler to the C++ compiler (see #16738). This would cause, for instance, `-std=gnu99` to be passed to the C++ compiler, causing spurious test failures. Fix this by maintaining a separate set of flags for C++ compilation invocations. - - - - - 71e75ba6 by Ömer Sinan Ağacan at 2019-06-13T23:35:19-04:00 Remove unused Unique field from StgFCallOp Fixes #16696 - - - - - ec25fe59 by Alp Mestanogullari at 2019-06-13T23:35:56-04:00 Hadrian: remove superfluous dependencies in Rules.Compile Each package's object files were 'need'ing the library files of all transitive dependencies of the current package, whichi is pointless since the said libraries are not needed until we link those object files together. This fixes #16759. - - - - - 3bc6df32 by Andreas Klebinger at 2019-06-13T23:36:34-04:00 Add Outputable instances for Float, Double. - - - - - effdd948 by Andrew Martin at 2019-06-14T10:48:13-04:00 Implement the -XUnliftedNewtypes extension. GHC Proposal: 0013-unlifted-newtypes.rst Discussion: https://github.com/ghc-proposals/ghc-proposals/pull/98 Issues: #15219, #1311, #13595, #15883 Implementation Details: Note [Implementation of UnliftedNewtypes] Note [Unifying data family kinds] Note [Compulsory newtype unfolding] This patch introduces the -XUnliftedNewtypes extension. When this extension is enabled, GHC drops the restriction that the field in a newtype must be of kind (TYPE 'LiftedRep). This allows types like Int# and ByteArray# to be used in a newtype. Additionally, coerce is made levity-polymorphic so that it can be used with newtypes over unlifted types. The bulk of the changes are in TcTyClsDecls.hs. With -XUnliftedNewtypes, getInitialKind is more liberal, introducing a unification variable to return the kind (TYPE r0) rather than just returning (TYPE 'LiftedRep). When kind-checking a data constructor with kcConDecl, we attempt to unify the kind of a newtype with the kind of its field's type. When typechecking a data declaration with tcTyClDecl, we again perform a unification. See the implementation note for more on this. Co-authored-by: Richard Eisenberg <rae at richarde.dev> - - - - - 5279dda8 by Ben Gamari at 2019-06-14T10:48:51-04:00 PrelRules: Don't break let/app invariant in shiftRule Previously shiftRule would rewrite as invalid shift like ``` let x = I# (uncheckedIShiftL# n 80) in ... ``` to ``` let x = I# (error "invalid shift") in ... ``` However, this breaks the let/app invariant as `error` is not okay-for-speculation. There isn't an easy way to avoid this so let's not try. Instead we just take advantage of the undefined nature of invalid shifts and return zero. Fixes #16742. - - - - - 503e830c by Ben Gamari at 2019-06-14T23:10:08-04:00 gitlab-ci: Lint testsuite for framework failures This introduces a new lint job checking for framework failures and listing broken tests. - - - - - b5ea9323 by Ben Gamari at 2019-06-14T23:10:08-04:00 lint: Only apply --interactive lint to testsuite .T files - - - - - 5c97211c by Ben Gamari at 2019-06-14T23:10:08-04:00 gitlab-ci: Lint the linters - - - - - 257165b4 by Alp Mestanogullari at 2019-06-14T23:10:46-04:00 Remove duplicates from 'ghc --info' output - - - - - 5da6c86f by Ben Gamari at 2019-06-15T15:14:01-04:00 Bump unix submodule Skips `executeFile001` test in `threaded2` way. Fixes #16814. - - - - - 20b4d5ec by Ben Gamari at 2019-06-15T23:32:38-04:00 Disable optimisation when building Cabal lib for stage0 This disables optimisation when building Cabal for Hadrian and stage0 `ghc-cabal`. Cabal is performance critical in neither case nor will any performance difference here be visible to the end-user. See #16817. - - - - - 76b7f619 by Ben Gamari at 2019-06-15T23:32:38-04:00 Disable optimisation when building Cabal in development flavours This updates the make and Hadrian build flavours targetting developers to disable optimisation when building the Cabal library. Cabal tends to tickle some very bad compiler performance cases (e.g. #16577) so disabling optimisation here makes a sizeable impact on overall build time. See #16817. - - - - - 0d2a4258 by Ben Gamari at 2019-06-15T23:33:13-04:00 testsuite: Introduce concurrent_ways set Previously we just tested for the threaded2 when determining whether to skip tests which are fragile under concurrent execution. However, this isn't the only way which is concurrent. - - - - - beacb6fd by Ben Gamari at 2019-06-15T23:33:13-04:00 testsuite: Skip hDuplicateTo001 in concurrent ways As noted in #16819, this operation is racy under concurrent execution. - - - - - ca721193 by Aiken Cairncross at 2019-06-15T23:33:50-04:00 Fix typo in error message - - - - - 57b71848 by Ben Gamari at 2019-06-15T23:34:25-04:00 testsuite: Add assertions that way lists are in fact lists Previously there were a few cases where operations like `omit_ways` were incorrectly passed a single way (e.g. `omit_ways('threaded2')`). This won't work as the author expected. - - - - - 25ee60cd by Ryan Scott at 2019-06-15T23:35:03-04:00 Synchronize ClsInst.doTyConApp with TcTypeable validity checks (#15862) Issue #15862 demonstrated examples of type constructors on which `TcTypeable.tyConIsTypeable` would return `False`, but the `Typeable` constraint solver in `ClsInst` (in particular, `doTyConApp`) would try to generate `Typeable` evidence for anyway, resulting in disaster. This incongruity was caused by the fact that `doTyConApp` was using a weaker validity check than `tyConIsTypeable` to determine if a type constructor warrants `Typeable` evidence or not. The solution, perhaps unsurprisingly, is to use `tyConIsTypeable` in `doTyConApp` instead. To avoid import cycles between `ClsInst` and `TcTypeable`, I factored out `tyConIsTypeable` into its own module, `TcTypeableValidity`. Fixes #15862. - - - - - 4138bf86 by Krzysztof Gogolewski at 2019-06-15T23:35:38-04:00 Remove dead code - - - - - db313f98 by Ben Gamari at 2019-06-16T06:26:38-04:00 base/Event/Poll: Drop POLLRDHUP enum item Previously the Event enumeration produced by hsc2hs would sometimes include a currently-unused POLLRDHUP item. This unused binding would result in a build failure. Drop it. - - - - - 81608e82 by Ben Gamari at 2019-06-16T06:26:38-04:00 testsuite: Fix T8602 on musl Musl wants hash-bangs on all executables. - - - - - a0f68379 by Ben Gamari at 2019-06-16T06:26:38-04:00 testsuite: Ensure T5423 flushes C output buffer Previously T5423 would fail to flush the printf output buffer. Consequently it was platform-dependent whether the C or Haskell print output would be emitted first. - - - - - 543dfaab by Ben Gamari at 2019-06-16T06:26:38-04:00 testsuite: Flush conc059's printf buffer Otherwise it the order out the Haskell and C output will be system-dependent. - - - - - e647752e by Ben Gamari at 2019-06-16T06:26:38-04:00 testsuite: Ensure that ffi005 output order is predictable The libc output buffer wasn't being flushed, making the order system-depedent. - - - - - 338336d3 by Ben Gamari at 2019-06-16T06:26:38-04:00 gitlab-ci: Build alpine release bindists - - - - - 75c6ccf7 by Alp Mestanogullari at 2019-06-16T06:27:17-04:00 fix runghc's GHC detection logic to cover the "in-tree Hadrian build" scenario Before this patch, runghc would only run the GHC detection logic on Windows and assume that it was invoked through a wrapper script on all other platforms. This patch lifts this limitation and makes that logic work for the scenario where someone is calling the runghc executable directly, without passing an explicit path to GHC. - - - - - 3c35e140 by Ben Gamari at 2019-06-16T19:38:51-04:00 testsuite: Really fix #16741 The previous fix, !1095, didn't work as `--show-iface` ignores `-dsuppress-ticks`. Rework the test instead. - - - - - b3bb1b06 by Ben Gamari at 2019-06-16T19:38:51-04:00 gitlab-ci: Don't allow failure of deb9-dwarf job This #16741 out of the way this should now pass. - - - - - b965de1e by Ömer Sinan Ağacan at 2019-06-16T19:39:29-04:00 Use TupleSections in CmmParse.y, simplify a few exprs - - - - - 63965ae3 by Ben Gamari at 2019-06-17T01:20:21-04:00 make: Clean includes/settings file Now since this is generated by the build system we should ensure that it is properly cleaned. [skip ci] - - - - - bb141114 by Siddharth Bhat at 2019-06-17T01:20:57-04:00 Add link to mfix.github.io/ghc in HACKING.md - - - - - 24afbfe9 by Ben Gamari at 2019-06-17T10:20:32-04:00 gitlab-ci: Run nofib on binary distributions Updates docker images to ensure that the `time` utility is available. - - - - - 62f0213d by Fumiaki Kinoshita at 2019-06-18T16:00:20-04:00 Data.Ord: give a field name getDown to Down - - - - - da33f2bb by Fumiaki Kinoshita at 2019-06-18T16:00:20-04:00 Add more newtype-derived instances to Data.Ord.Down Metric Increase: haddock.base - - - - - dbf9ca20 by Ben Gamari at 2019-06-18T16:00:56-04:00 testsuite: Add testcase for #16689 - - - - - 29ec33cd by Ben Gamari at 2019-06-18T16:00:56-04:00 SafeHaskell: Don't throw -Wsafe warning if module is declared Safe Fixes #16689. - - - - - a491e40c by Ben Gamari at 2019-06-18T16:01:31-04:00 hadrian: Compile UserSettings with -O0 This guarantees that the interface file for `UserSettings` doesn't contain any unfoldings, ensuring that a change in it requires minimal rebuilds. - - - - - 74bd6b22 by Ben Gamari at 2019-06-18T16:02:07-04:00 testsuite: Add test for #16832 - - - - - 6a92f59d by Ben Gamari at 2019-06-18T16:02:42-04:00 gitlab-ci: Run alpine builds during nightly job - - - - - 4549cadf by Andreas Klebinger at 2019-06-18T16:03:19-04:00 Make sure mkSplitUniqSupply stores the precomputed mask only. mkSplitUniqSupply was lazy on the boxed char. This caused a bunch of issues: * The closure captured the boxed Char * The mask was recomputed on every split of the supply. * It also caused the allocation of MkSplitSupply to happen in it's own (allocated) closure. The reason of which I did not further investigate. We know force the computation of the mask inside mkSplitUniqSupply. * This way the mask is computed at most once per UniqSupply creation. * It allows ww to kick in, causing the closure to retain the unboxed value. Requesting Uniques in a loop is now faster by about 20%. I did not check the impact on the overall compiler, but I added a test to avoid regressions. - - - - - 8584430e by Ömer Sinan Ağacan at 2019-06-19T15:00:11+03:00 Fix a Note name in CmmNode ("Continuation BlockIds" is referenced in CmmProcPoint) [skip ci] - - - - - 9d58554f by Ömer Sinan Ağacan at 2019-06-19T22:14:26-04:00 Properly trim IdInfos of DFunIds and PatSyns in TidyPgm Not doing this right caused #16608. We now properly trim IdInfos of DFunIds and PatSyns. Some further refactoring done by SPJ. Two regression tests T16608_1 and T16608_2 added. Fixes #16608 - - - - - 39c758e1 by Roland Senn at 2019-06-19T22:15:04-04:00 Fix #1620: ModBreaks.modBreaks_array not initialised After a :cd command and after setting some package flags, GHCi unloads all loaded modules by resetting the list of targets. This patch deletes eventually defined debugger breakpoints, before GHCi resets the target list. The common code is factored out into the new function clearAllTargets. - - - - - 3c9b57b0 by Simon Peyton Jones at 2019-06-19T22:15:39-04:00 Fix two places that failed the substitution invariant The substition invariant relies on keeping the in-scope set in sync, and we weren't always doing so, which means that a DEBUG compiler crashes sometimes with an assertion failure This patch fixes a couple more cases. Still not validate clean (with -DEEBUG) but closer! - - - - - 48fb3482 by Simon Peyton Jones at 2019-06-19T22:15:39-04:00 Fix typechecking of partial type signatures Partial type sigs had grown hair. tcHsParialSigType was doing lots of unnecessary work, and tcInstSig was cloning it unnecessarily -- and the result didn't even work: #16728. This patch cleans it all up, described by TcHsType Note [Checking parital type signatures] I basically just deleted code... but very carefully! Some refactoring along the way * Distinguish more explicintly between "anonymous" wildcards "_" and "named" wildcards "_a". I changed the names of a number of functions to make this distinction much more apparent. The patch also revealed that the code in `TcExpr` that implements the special typing rule for `($)` was wrong. It called `getRuntimeRep` in a situation where where was no particular reason to suppose that the thing had kind `TYPE r`. This caused a crash in typecheck/should_run/T10846. The fix was easy, and actually simplifies the code in `TcExpr` quite a bit. Hooray. - - - - - 3ae23992 by Simon Peyton Jones at 2019-06-19T22:15:39-04:00 Comments and tiny refactor * Added Note [Quantified varaibles in partial type signatures] in TcRnTypes * Kill dVarSetElemsWellScoped; it was only called in one function, quantifyTyVars. I inlined it because it was only scopedSort . dVarSetElems * Kill Type.tyCoVarsOfBindersWellScoped, never called. - - - - - bff2f24b by John Ericson at 2019-06-19T22:16:16-04:00 Move 'Platform' to ghc-boot ghc-pkg needs to be aware of platforms so it can figure out which subdire within the user package db to use. This is admittedly roundabout, but maybe Cabal could use the same notion of a platform as GHC to good affect too. - - - - - a298b96e by John Ericson at 2019-06-19T22:16:16-04:00 Add 'stringEncodeArch' and 'stringEncodeOS' to GHC.Platform - - - - - d406a16a by John Ericson at 2019-06-19T22:16:16-04:00 ghc-pkg needs settings file to un-hardcode target platform This matches GHC itself getting the target platform from there. - - - - - aa4891a7 by Ben Gamari at 2019-06-19T22:16:51-04:00 users-guide: Fix a variety of broken links and syntax - - - - - fe819dd6 by Ben Gamari at 2019-06-19T22:16:51-04:00 users-guide: Update -Wsafe description for #16689 We no longer emit a warning when a safe module is explicitly declared as such. - - - - - c311277b by Matthías Páll Gissurarson at 2019-06-21T03:21:21+02:00 Add HoleFitPlugins and RawHoleFits This patch adds a new kind of plugin, Hole fit plugins. These plugins can change what candidates are considered when looking for valid hole fits, and add hole fits of their own. The type of a plugin is relatively simple, ``` type FitPlugin = TypedHole -> [HoleFit] -> TcM [HoleFit] type CandPlugin = TypedHole -> [HoleFitCandidate] -> TcM [HoleFitCandidate] data HoleFitPlugin = HoleFitPlugin { candPlugin :: CandPlugin , fitPlugin :: FitPlugin } data TypedHole = TyH { tyHRelevantCts :: Cts -- ^ Any relevant Cts to the hole , tyHImplics :: [Implication] -- ^ The nested implications of the hole with the -- innermost implication first. , tyHCt :: Maybe Ct -- ^ The hole constraint itself, if available. } This allows users and plugin writers to interact with the candidates and fits as they wish, even going as far as to allow them to reimplement the current functionality (since `TypedHole` contains all the relevant information). As an example, consider the following plugin: ``` module HolePlugin where import GhcPlugins import TcHoleErrors import Data.List (intersect, stripPrefix) import RdrName (importSpecModule) import TcRnTypes import System.Process plugin :: Plugin plugin = defaultPlugin { holeFitPlugin = hfp, pluginRecompile = purePlugin } hfp :: [CommandLineOption] -> Maybe HoleFitPluginR hfp opts = Just (fromPureHFPlugin $ HoleFitPlugin (candP opts) (fp opts)) toFilter :: Maybe String -> Maybe String toFilter = flip (>>=) (stripPrefix "_module_") replace :: Eq a => a -> a -> [a] -> [a] replace match repl str = replace' [] str where replace' sofar (x:xs) | x == match = replace' (repl:sofar) xs replace' sofar (x:xs) = replace' (x:sofar) xs replace' sofar [] = reverse sofar -- | This candidate plugin filters the candidates by module, -- using the name of the hole as module to search in candP :: [CommandLineOption] -> CandPlugin candP _ hole cands = do let he = case tyHCt hole of Just (CHoleCan _ h) -> Just (occNameString $ holeOcc h) _ -> Nothing case toFilter he of Just undscModName -> do let replaced = replace '_' '.' undscModName let res = filter (greNotInOpts [replaced]) cands return $ res _ -> return cands where greNotInOpts opts (GreHFCand gre) = not $ null $ intersect (inScopeVia gre) opts greNotInOpts _ _ = True inScopeVia = map (moduleNameString . importSpecModule) . gre_imp -- Yes, it's pretty hacky, but it is just an example :) searchHoogle :: String -> IO [String] searchHoogle ty = lines <$> (readProcess "hoogle" [(show ty)] []) fp :: [CommandLineOption] -> FitPlugin fp ("hoogle":[]) hole hfs = do dflags <- getDynFlags let tyString = showSDoc dflags . ppr . ctPred <$> tyHCt hole res <- case tyString of Just ty -> liftIO $ searchHoogle ty _ -> return [] return $ (take 2 $ map (RawHoleFit . text . ("Hoogle says: " ++)) res) ++ hfs fp _ _ hfs = return hfs ``` with this plugin available, you can compile the following file ``` {-# OPTIONS -fplugin=HolePlugin -fplugin-opt=HolePlugin:hoogle #-} module Main where import Prelude hiding (head, last) import Data.List (head, last) t :: [Int] -> Int t = _module_Prelude g :: [Int] -> Int g = _module_Data_List main :: IO () main = print $ t [1,2,3] ``` and get the following output: ``` Main.hs:14:5: error: • Found hole: _module_Prelude :: [Int] -> Int Or perhaps ‘_module_Prelude’ is mis-spelled, or not in scope • In the expression: _module_Prelude In an equation for ‘t’: t = _module_Prelude • Relevant bindings include t :: [Int] -> Int (bound at Main.hs:14:1) Valid hole fits include Hoogle says: GHC.List length :: [a] -> Int Hoogle says: GHC.OldList length :: [a] -> Int t :: [Int] -> Int (bound at Main.hs:14:1) g :: [Int] -> Int (bound at Main.hs:17:1) length :: forall (t :: * -> *) a. Foldable t => t a -> Int with length @[] @Int (imported from ‘Prelude’ at Main.hs:5:1-34 (and originally defined in ‘Data.Foldable’)) maximum :: forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a with maximum @[] @Int (imported from ‘Prelude’ at Main.hs:5:1-34 (and originally defined in ‘Data.Foldable’)) (Some hole fits suppressed; use -fmax-valid-hole-fits=N or -fno-max-valid-hole-fits) | 14 | t = _module_Prelude | ^^^^^^^^^^^^^^^ Main.hs:17:5: error: • Found hole: _module_Data_List :: [Int] -> Int Or perhaps ‘_module_Data_List’ is mis-spelled, or not in scope • In the expression: _module_Data_List In an equation for ‘g’: g = _module_Data_List • Relevant bindings include g :: [Int] -> Int (bound at Main.hs:17:1) Valid hole fits include Hoogle says: GHC.List length :: [a] -> Int Hoogle says: GHC.OldList length :: [a] -> Int g :: [Int] -> Int (bound at Main.hs:17:1) head :: forall a. [a] -> a with head @Int (imported from ‘Data.List’ at Main.hs:7:19-22 (and originally defined in ‘GHC.List’)) last :: forall a. [a] -> a with last @Int (imported from ‘Data.List’ at Main.hs:7:25-28 (and originally defined in ‘GHC.List’)) | 17 | g = _module_Data_List ``` This relatively simple plugin has two functions, as an example of what is possible to do with hole fit plugins. The candidate plugin starts by filtering the candidates considered by module, indicated by the name of the hole (`_module_Data_List`). The second function is in the fit plugin, where the plugin invokes a local hoogle instance to search by the type of the hole. By adding the `RawHoleFit` type, we can also allow these completely free suggestions, used in the plugin above to display fits found by Hoogle. Additionally, the `HoleFitPluginR` wrapper can be used for plugins to maintain state between invocations, which can be used to speed up invocation of plugins that have expensive initialization. ``` -- | HoleFitPluginR adds a TcRef to hole fit plugins so that plugins can -- track internal state. Note the existential quantification, ensuring that -- the state cannot be modified from outside the plugin. data HoleFitPluginR = forall s. HoleFitPluginR { hfPluginInit :: TcM (TcRef s) -- ^ Initializes the TcRef to be passed to the plugin , hfPluginRun :: TcRef s -> HoleFitPlugin -- ^ The function defining the plugin itself , hfPluginStop :: TcRef s -> TcM () -- ^ Cleanup of state, guaranteed to be called even on error } ``` Of course, the syntax here is up for debate, but hole fit plugins allow us to experiment relatively easily with ways to interact with typed-holes without having to dig deep into GHC. Reviewers: bgamari Subscribers: rwbarton, carter Differential Revision: https://phabricator.haskell.org/D5373 - - - - - 2485c08a by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Skip dynamicToo006 when dynamic linking is not available This was previously failling on Windows. - - - - - aa516431 by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Mark T3372 as fragile on Windows On Windows we must lock package databases even when opening for read-only access. This means that concurrent GHC sessions are very likely to fail with file lock contention. See #16773. - - - - - 2eedb120 by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Add stderr output for UnsafeInfered02 on Windows This test uses TemplateHaskell causing GHC to build dynamic objects on platforms where dynamic linking is available. However, Windows doesn't support dynamic linking. Consequently the test would fail on Windows with: ```patch --- safeHaskell/safeInfered/UnsafeInfered02.run/UnsafeInfered02.stderr.normalised 2019-06-04 15:10:10.521594200 +0000 +++ safeHaskell/safeInfered/UnsafeInfered02.run/UnsafeInfered02.comp.stderr.normalised 2019-06-04 15:10:10.523546200 +0000 @@ -1,5 +1,5 @@ -[1 of 2] Compiling UnsafeInfered02_A ( UnsafeInfered02_A.hs, UnsafeInfered02_A.o, UnsafeInfered02_A.dyn_o ) -[2 of 2] Compiling UnsafeInfered02 ( UnsafeInfered02.hs, UnsafeInfered02.o, UnsafeInfered02.dyn_o ) +[1 of 2] Compiling UnsafeInfered02_A ( UnsafeInfered02_A.hs, UnsafeInfered02_A.o ) +[2 of 2] Compiling UnsafeInfered02 ( UnsafeInfered02.hs, UnsafeInfered02.o ) UnsafeInfered02.hs:4:1: UnsafeInfered02_A: Can't be safely imported! ``` The other approach I considered for this issue is to pass `-v0` to GHC. However, I felt we should probably do this consistently for all of the tests in this directory and this would take more time than I currently have. - - - - - 3967d13a by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Mark OldModLocation as broken on Windows Strangely the path it emits contains duplicate path delimiters (#16772), ```patch --- ghc-api/downsweep/OldModLocation.run/OldModLocation.stderr.normalised 2019-06-04 14:40:26.326075000 +0000 +++ ghc-api/downsweep/OldModLocation.run/OldModLocation.run.stderr.normalised 2019-06-04 14:40:26.328029200 +0000 @@ -1 +1 @@ -[Just "A.hs",Just "mydir/B.hs"] +[Just "A.hs",Just "mydir//B.hs"] ``` - - - - - 31f2ea68 by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Mark T7170 as broken on Windows Due to #16801. - - - - - 7bd1c3e1 by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Mark T7702 as broken on Windows Due to #16799. - - - - - 84900724 by Ben Gamari at 2019-06-21T13:32:34-04:00 testsuite: Mark T15633a and T15633b as fragile on Windows As noted in #16813, these tests seem to be fragile on Windows. - - - - - 49fff41d by Ben Gamari at 2019-06-21T13:32:34-04:00 linker: Disable code unloading As noted in #16841, there are currently a variety of bugs in the unloading logic. These only affect Windows since code unloading is disabled on Linux, where we build with `GhcDynamic=YES` by default. In the interest of getting the tree green on Windows disable code unloading until the issues are resolved. - - - - - e0595d22 by Ben Gamari at 2019-06-22T09:36:53-04:00 testsuite: Mark T16608_* as fragile on Darwin As noted in #16855. - - - - - 655c6e26 by Ben Gamari at 2019-06-22T10:06:05-04:00 ghci: Don't rely on resolution of System.IO to base module Previously we would hackily evaluate a textual code snippet to compute actions to disable I/O buffering and flush the stdout/stderr handles. This broke in a number of ways (#15336, #16563). Instead we now ship a module (`GHC.GHCi.Helpers`) with `base` containing the needed actions. We can then easily refer to these via `Orig` names. - - - - - 8f8fc31b by Ben Gamari at 2019-06-22T10:06:05-04:00 testsuite: Add test for #16563 - - - - - 22e721c1 by Ben Gamari at 2019-06-22T10:06:05-04:00 testsuite: Mark T5611 as broken in ghci way As described in #16845. - - - - - b0d6bf2a by Ben Gamari at 2019-06-22T10:06:05-04:00 rts: Reset STATIC_LINK field of reverted CAFs When we revert a CAF we must reset the STATIC_LINK field lest the GC might ignore the CAF (e.g. as it carries the STATIC_FLAG_LIST flag) and will consequently overlook references to object code that we are trying to unload. This would result in the reachable object code being unloaded. See Note [CAF lists] and Note [STATIC_LINK fields]. This fixes #16842. Idea-due-to: Phuong Trinh <lolotp at fb.com> - - - - - 1f2fff89 by Ben Gamari at 2019-06-22T10:06:05-04:00 testsuite: Add caf_crash testcase - - - - - ade3db53 by Ben Gamari at 2019-06-23T17:19:48-04:00 testsuite: Test for #13786 - - - - - 5a502cd1 by Ben Gamari at 2019-06-23T17:19:48-04:00 ghci: Load static objects in batches Previously in the case where GHC was dynamically linked we would load static objects one-by-one by linking each into its own shared object and dlopen'ing each in order. However, this meant that the link would fail in the event that the objects had cyclic symbol dependencies. Here we fix this by merging each "run" of static objects into a single shared object and loading this. Fixes #13786 for the case where GHC is dynamically linked. - - - - - 9bbcc3be by Ryan Scott at 2019-06-23T17:20:41-04:00 Refactor UnliftedNewtypes-relation kind signature validity checks This fixes three infelicities related to the programs that are (and aren't) accepted with `UnliftedNewtypes`: * Enabling `UnliftedNewtypes` would permit newtypes to have return kind `Id Type`, which had disastrous results (i.e., GHC panics). * Data family declarations ending in kind `TYPE r` (for some `r`) weren't being accepted if `UnliftedNewtypes` wasn't enabled, despite the GHC proposal specifying otherwise. * GHC wasn't warning about programs that _would_ typecheck if `UnliftedNewtypes` were enabled in certain common cases. As part of fixing these issues, I factored out the logic for checking all of the various properties about data type/data family return kinds into a single `checkDataKindSig` function. I also cleaned up some of the formatting in the existing error message that gets thrown. Fixes #16821, fixes #16827, and fixes #16829. - - - - - 71aca77c by Erik de Castro Lopo at 2019-06-24T01:11:46-04:00 Fixes for LLVM 7 LLVM version numberinf changed recently. Previously, releases were numbered 4.0, 5.0 and 6.0 but with version 7, they dropped the redundant ".0". Fix requires for Llvm detection and some code. - - - - - 581cbc28 by Erik de Castro Lopo at 2019-06-24T01:12:22-04:00 Add MonadFail instance for ParserM - - - - - 15b26223 by Andrey Mokhov at 2019-06-25T01:36:10-04:00 Fix cyclic dependencies when using --configure This resolves #16809 (https://gitlab.haskell.org/ghc/ghc/issues/16809). This patch removes the unnecessary dependency on configure-generated flags `windowsHost`, `osxHost` and `iosHost`, using the information provided by the module `System.Info` instead. We also take care to use the `CrossCompiling` flag generated by the configure script only after the latter had a chance to run. - - - - - ebd63e8d by Ömer Sinan Ağacan at 2019-06-25T01:36:50-04:00 Simplify link_caf and mkForeignLabel functions - - - - - c346585b by Ben Gamari at 2019-06-25T08:37:46-04:00 testsuite: A major revamp of the driver This tries to put the testsuite driver into a slightly more maintainable condition: * Add type annotations where easily done * Use pathlib.Path instead of str paths * Make it pass the mypy typechecker - - - - - bb40bd37 by Ben Gamari at 2019-06-25T08:37:46-04:00 testsuite: Fix a few issues in JUnit output * Make it pass mypy * Fix a typo in test name field * Report more stderr output * Report stdout output - - - - - 95f56853 by Ben Gamari at 2019-06-25T08:37:46-04:00 gitlab-ci: Add testsuite typechecking lint - - - - - 9542ab06 by Ben Gamari at 2019-06-25T08:38:22-04:00 testsuite: Don't run T16525a with -DS unless compiler_debugged Originally I was thinking of just skipping the test unless compiled_debugged==True. However, the test will likely be useful even without -DS, so let's run it either way. - - - - - d0993a29 by Ben Gamari at 2019-06-25T08:38:22-04:00 testsuite: Fix expected output for caf_crash - - - - - 757b71d9 by Ben Gamari at 2019-06-25T08:38:22-04:00 testsuite: Mark ghci058 as broken on Windows Due to #16858. - - - - - 38ded743 by Siddharth Bhat at 2019-06-25T15:15:16+02:00 [skip ci] Typo fix: b*ar*nches -> b*ra*nches - - - - - 8a03d5a1 by Ben Gamari at 2019-06-25T22:20:24-04:00 testsuite: Add test for #16846 - - - - - 5ff0a171 by Ben Gamari at 2019-06-25T22:20:24-04:00 CoreToStg: Enable CAFfyness checking with -dstg-lint The debugging involved in finding #16846 wouldn't have been necessary had the consistentCafInfo check been enabled. However, :wq - - - - - cac8dc9f by Ben Gamari at 2019-06-25T22:20:24-04:00 Don't eta-expand unsaturated primops Previously, as described in Note [Primop wrappers], `hasNoBinding` would return False in the case of `PrimOpId`s. This would result in eta expansion of unsaturated primop applications during CorePrep. Not only did this expansion result in unnecessary allocations, but it also meant lead to rather nasty inconsistencies between the CAFfy-ness determinations made by TidyPgm and CorePrep. This fixes #16846. - - - - - b90437d8 by Ben Gamari at 2019-06-25T22:20:59-04:00 testsuite: Unbreak T16608 tests Sleep to avoid non-determinism due to Darwin's poor mtime resolution. Fixes #16855. - - - - - ff2b99e1 by Ömer Sinan Ağacan at 2019-06-25T22:21:38-04:00 Remove unused UniqSupply functions - - - - - 4c2127c4 by Ben Gamari at 2019-06-25T22:52:26-04:00 Bump containers submodule to v0.6.2.1 - - - - - 5c3f2080 by Ben Gamari at 2019-06-25T22:52:26-04:00 Bump Cabal submodule to what will become 3.0.0.0 Metric Increase: haddock.Cabal - - - - - a863c44f by Oleg Grenrus at 2019-06-25T23:25:08-04:00 Add -Winferred-safe-imports warning This commit partly reverts e69619e923e84ae61a6bb4357f06862264daa94b commit by reintroducing Sf_SafeInferred SafeHaskellMode. We preserve whether module was declared or inferred Safe. When declared-Safe module imports inferred-Safe, we warn. This inferred status is volatile, often enough it's a happy coincidence, something which cannot be relied upon. However, explicitly Safe or Trustworthy packages won't accidentally become Unsafe. Updates haddock submodule. - - - - - 8ec5ceb0 by Oleg Grenrus at 2019-06-25T23:25:08-04:00 Add -Wmissing-safe-haskell-mode warning - - - - - c99d9aab by Ben Gamari at 2019-06-26T08:15:02-04:00 testsuite: Fix T16832 The test seems to have been missing the name of its script and didn't build with HEAD. How it made it through CI is beyond me. - - - - - e0899925 by Siddharth Bhat at 2019-06-26T08:16:30-04:00 [skip ci] add a blurb about the purpose of Printer.c - - - - - 58e84b30 by Ben Gamari at 2019-06-26T08:18:25-04:00 testsuite: Use safe FFI call in T5611 The original issue, #5611, was concerned with safe calls. However, the test inexplicably used an unsafe call. Fix this. - - - - - 12752342 by Ben Gamari at 2019-06-26T08:18:25-04:00 testsuite: Add T5611a This is the same as T5611 but with an unsafe call to sleep. - - - - - 551b79e4 by Ben Gamari at 2019-06-26T08:18:25-04:00 testsuite: Mark T5611 and T5611a as fragile - - - - - 44d08c32 by Ben Gamari at 2019-06-26T08:20:54-04:00 testsuite: Run and report on fragile tests This allows us to run (but ignore the result of) fragile testcases. Hopefully this should allow us to more easily spot when a fragile test becomes un-fragile. - - - - - 1c4f18d0 by Ben Gamari at 2019-06-26T08:20:54-04:00 testsuite: More type signatures - - - - - a586b33f by Matthew Pickering at 2019-06-27T10:42:29-04:00 rts: Correct handling of LARGE ARR_WORDS in LDV profiler This implements the correct fix for #11627 by skipping over the slop (which is zeroed) rather than adding special case logic for LARGE ARR_WORDS which runs the risk of not performing a correct census by ignoring any subsequent blocks. This approach implements similar logic to that in Sanity.c - - - - - ed4cbd93 by Matthew Pickering at 2019-06-27T10:42:29-04:00 rts: Correct assertion in LDV_recordDead It is possible that void_total is exactly equal to not_used and the other assertions for this check for <= rather than <. - - - - - 07cffc49 by Matthew Pickering at 2019-06-27T10:42:29-04:00 rts: Do not traverse nursery for dead closures in LDV profile It is important that `heapCensus` and `LdvCensusForDead` traverse the same areas. `heapCensus` increases the `not_used` counter which tracks how many closures are live but haven't been used yet. `LdvCensusForDead` increases the `void_total` counter which tracks how many dead closures there are. The `LAG` is then calculated by substracting the `void_total` from `not_used` and so it is essential that `not_used >= void_total`. This fact is checked by quite a few assertions. However, if a program has low maximum residency but allocates a lot in the nursery then these assertions were failing (see #16753 and #15903) because `LdvCensusForDead` was observing dead closures from the nursery which totalled more than the `not_used`. The same closures were not counted by `heapCensus`. Therefore, it seems that the correct fix is to make `LdvCensusForDead` agree with `heapCensus` and not traverse the nursery for dead closures. Fixes #16100 #16753 #15903 #8982 - - - - - c1f67887 by Roland Senn at 2019-06-27T10:43:10-04:00 Improve doc for :type-at. (#14780) - - - - - 52f10216 by Roland Zumkeller at 2019-06-27T10:43:47-04:00 configure: prefer cc over gcc Fixes #16857. - - - - - 90e0ab7d by Sylvain Henry at 2019-06-27T10:44:25-04:00 Fix Happy deps for Stack (#16825) - - - - - d35cec7a by Fraser Tweedale at 2019-06-27T10:45:01-04:00 getExecutablePath: get path from sysctl on FreeBSD - - - - - 2a68b8b7 by nineonine at 2019-06-27T10:45:39-04:00 Fix #16805 by formatting warning message - - - - - 217258d0 by Ben Gamari at 2019-06-27T10:46:18-04:00 testsuite: Add more type annotations to perf_notes - - - - - 4ec233ec by Sylvain Henry at 2019-06-27T23:58:37-04:00 Fix GCC warnings with __clear_cache builtin (#16867) - - - - - ef6d9a50 by Artem Pelenitsyn at 2019-06-27T23:59:15-04:00 typo in the docs for DynFlags.hs - - - - - 11bac115 by Travis Whitaker at 2019-06-28T15:25:05-04:00 Correct closure observation, construction, and mutation on weak memory machines. Here the following changes are introduced: - A read barrier machine op is added to Cmm. - The order in which a closure's fields are read and written is changed. - Memory barriers are added to RTS code to ensure correctness on out-or-order machines with weak memory ordering. Cmm has a new CallishMachOp called MO_ReadBarrier. On weak memory machines, this is lowered to an instruction that ensures memory reads that occur after said instruction in program order are not performed before reads coming before said instruction in program order. On machines with strong memory ordering properties (e.g. X86, SPARC in TSO mode) no such instruction is necessary, so MO_ReadBarrier is simply erased. However, such an instruction is necessary on weakly ordered machines, e.g. ARM and PowerPC. Weam memory ordering has consequences for how closures are observed and mutated. For example, consider a closure that needs to be updated to an indirection. In order for the indirection to be safe for concurrent observers to enter, said observers must read the indirection's info table before they read the indirectee. Furthermore, the entering observer makes assumptions about the closure based on its info table contents, e.g. an INFO_TYPE of IND imples the closure has an indirectee pointer that is safe to follow. When a closure is updated with an indirection, both its info table and its indirectee must be written. With weak memory ordering, these two writes can be arbitrarily reordered, and perhaps even interleaved with other threads' reads and writes (in the absence of memory barrier instructions). Consider this example of a bad reordering: - An updater writes to a closure's info table (INFO_TYPE is now IND). - A concurrent observer branches upon reading the closure's INFO_TYPE as IND. - A concurrent observer reads the closure's indirectee and enters it. (!!!) - An updater writes the closure's indirectee. Here the update to the indirectee comes too late and the concurrent observer has jumped off into the abyss. Speculative execution can also cause us issues, consider: - An observer is about to case on a value in closure's info table. - The observer speculatively reads one or more of closure's fields. - An updater writes to closure's info table. - The observer takes a branch based on the new info table value, but with the old closure fields! - The updater writes to the closure's other fields, but its too late. Because of these effects, reads and writes to a closure's info table must be ordered carefully with respect to reads and writes to the closure's other fields, and memory barriers must be placed to ensure that reads and writes occur in program order. Specifically, updates to a closure must follow the following pattern: - Update the closure's (non-info table) fields. - Write barrier. - Update the closure's info table. Observing a closure's fields must follow the following pattern: - Read the closure's info pointer. - Read barrier. - Read the closure's (non-info table) fields. This patch updates RTS code to obey this pattern. This should fix long-standing SMP bugs on ARM (specifically newer aarch64 microarchitectures supporting out-of-order execution) and PowerPC. This fixes issue #15449. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - bd660ede by Ben Gamari at 2019-06-28T15:25:30-04:00 rts: Assert that LDV profiling isn't used with parallel GC I'm not entirely sure we are careful about ensuring this; this is a last-ditch check. - - - - - 82693938 by Moritz Angermann at 2019-07-02T16:18:05-04:00 Add _GLOBAL_OFFSET_TABLE_ support This adds lookup logic for _GLOBAL_OFFSET_TABLE_ as well as relocation logic for R_ARM_BASE_PREL and R_ARM_GOT_BREL which the gnu toolchain (gas, gcc, ...) prefers to produce. Apparently recent llvm toolchains will produce those as well. - - - - - 348e3f8e by Edward Amsden at 2019-07-02T16:18:05-04:00 Lookup _GLOBAL_OFFSET_TABLE by symbol->addr when doing relocations - - - - - e9abcad4 by Moritz Angermann at 2019-07-02T16:18:05-04:00 No atomics on arm32; this will just yield stubs. As such the internal linker will fail for them. The alternative would be to implement them as stubs in the linker and have them barf when called. > Not all operations are supported by all target processors. If a particular operation cannot be implemented on the target processor, a warning is generated and a call an external function is generated. The external function carries the same name as the built-in version, with an additional suffix ‘_n’ where n is the size of the data type. (https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html) - - - - - 023a2bc7 by Ben Gamari at 2019-07-02T16:18:05-04:00 Apply suggestion to rts/linker/elf_got.c - - - - - 0bed9647 by Ben Gamari at 2019-07-02T16:18:05-04:00 Apply suggestion to rts/linker/Elf.c - - - - - cef80c0b by nineonine at 2019-07-02T16:18:44-04:00 Fix #15843 by extending Template Haskell AST for tuples to support sections - - - - - 294b55dc by Eric Wolf at 2019-07-02T16:19:21-04:00 Add test for #16575 just use the test to show the defective behaviour, so we can see the difference, when it gets fixed - - - - - 60b9eab9 by Ömer Sinan Ağacan at 2019-07-02T16:19:59-04:00 Fix stage 1 warnings - - - - - df3e5b74 by David Eichmann at 2019-07-02T16:20:36-04:00 Hadrian: disable cloud build cache for symlinks #16800 This is a temporary workaround shake not supporting symlinks when using cloud/cached builds. - - - - - acd79558 by Abhiroop Sarkar at 2019-07-03T09:33:39-04:00 Add support for SIMD operations in the NCG This adds support for constructing vector types from Float#, Double# etc and performing arithmetic operations on them Cleaned-Up-By: Ben Gamari <ben at well-typed.com> - - - - - 973c61b5 by Ben Gamari at 2019-07-03T09:34:16-04:00 gitlab-ci: Fix doc-tarball job Previously we used the deb9-debug job which used the `validate` build flavour which disabled `BUILD_SPHINX_PDF`. Fix this. Fixes #16890. - - - - - a25f6f55 by Ryan Scott at 2019-07-03T09:34:54-04:00 Bump template-haskell version to 2.16.0.0 Commit cef80c0b9edca3d21b5c762f51dfbab4c5857d8a debuted a breaking change to `template-haskell`, so in order to guard against it properly with CPP, we need to bump the `template-haskell` version number accordingly. - - - - - f7a2e709 by Ben Gamari at 2019-07-04T15:29:49-04:00 Bump parsec submodule to 3.1.14.0 - - - - - d7f7e1ed by Siddharth Bhat at 2019-07-04T21:22:00-04:00 Make printer untag when chasing a pointer in a RET_FUN frame This is to mimic what `Scav.c` does. This should fix a crash in the printer. - - - - - 675d27fc by Ben Gamari at 2019-07-04T21:22:35-04:00 gitlab: Reduce size of template headings - - - - - 679427f8 by Vladislav Zavialov at 2019-07-04T21:23:10-04:00 Produce all DerivInfo in tcTyAndClassDecls Before this refactoring: * DerivInfo for data family instances was returned from tcTyAndClassDecls * DerivInfo for data declarations was generated with mkDerivInfos and added at a later stage of the pipeline in tcInstDeclsDeriv After this refactoring: * DerivInfo for both data family instances and data declarations is returned from tcTyAndClassDecls in a single list. This uniform treatment results in a more convenient arrangement to fix #16731. - - - - - 53aa59f3 by Simon Peyton Jones at 2019-07-04T21:23:49-04:00 Add a missing zonk (fixes #16902) In the eager unifier, when unifying (tv1 ~ tv2), when we decide to swap them over, to unify (tv2 ~ tv1), I'd forgotten to ensure that tv1's kind was fully zonked, which is an invariant of uUnfilledTyVar2. That could lead us to build an infinite kind, or (in the case of #16902) update the same unification variable twice. Yikes. Now we get an error message rather than non-termination, which is much better. The error message is not great, but it's a very strange program, and I can't see an easy way to improve it, so for now I'm just committing this fix. Here's the decl data F (a :: k) :: (a ~~ k) => Type where MkF :: F a and the rather error message of which I am not proud T16902.hs:11:10: error: • Expected a type, but found something with kind ‘a1’ • In the type ‘F a’ - - - - - ed662901 by Daniel Gröber at 2019-07-04T21:24:26-04:00 rts: Fix -hT option with profiling rts In dumpCensus we switch/case on doHeapProfile twice. The second switch tries to barf on unknown doHeapProfile modes but HEAP_BY_CLOSURE_TYPE is checked by the first switch and not included in the second. So when trying to pass -hT to the profiling rts it barfs. This commit simply merges the two switches into one which fixes this problem. - - - - - 80afdf6b by Simon Peyton Jones at 2019-07-04T21:25:05-04:00 Fix over-eager implication constraint discard Ticket #16247 showed that we were discarding an implication constraint that had empty ic_wanted, when we still needed to keep it so we could check whether it had a bad telescope. Happily it's a one line fix. All the rest is comments! - - - - - f002250a by Andreas Klebinger at 2019-07-04T21:25:43-04:00 Dont gather ticks when only striping them in STG. Adds stripStgTicksTopE which only returns the stripped expression. So far we also allocated a list for the stripped ticks which was never used. Allocation difference is as expected very small but present. About 0.02% difference when compiling with -O. - - - - - a76b233d by Artem Pelenitsyn at 2019-07-05T07:06:55-04:00 Make all submodules have absolute URLs The relative URLs were a workaround to let most contributors fork from Github due to a weakness in the haskell.org server. This workaround is no longer needed. And relative submodule URLs are an impediment to forking which makes contributions harder than they should be. The URLs are chosen to clone from https, because this makes sure that anybody, even not a registered Gitlab user, can clone a fork recursively. - - - - - 62b82135 by Ryan Scott at 2019-07-05T07:07:38-04:00 More sensible SrcSpans for recursive pattern synonym errors (#16900) Attach the `SrcSpan` of the first pattern synonym binding involved in the recursive group when throwing the corresponding error message, similarly to how it is done for type synonyms. Fixes #16900. - - - - - 2fd1ed54 by nineonine at 2019-07-05T07:08:17-04:00 Fix #16895 by checking whether infix expression operator is a variable - - - - - 03f5adcd by David Eichmann at 2019-07-08T07:07:10-04:00 Bump Shake and copy instead of hard link from cloud cache This is important as in hard link mode shake makes all such files read only to avoid accidentally modifying cache files via the hard link. It turns out, many Hadrian rules attempt read access to such files and hence fail in the hard link mode. These rules could be refactored to avoid write access, but using copy instead of hard link a much simpler solution. - - - - - 5af815f2 by Kevin Buhr at 2019-07-08T07:07:11-04:00 Add test for old issue w/ bad source locations for warnings in .lhs files (#515) - - - - - 6a03d77b by Ryan Scott at 2019-07-09T11:52:45-04:00 Use an empty data type in TTG extension constructors (#15247) To avoid having to `panic` any time a TTG extension constructor is consumed, this MR introduces an uninhabited 'NoExtCon' type and uses that in every extension constructor's type family instance where it is appropriate. This also introduces a 'noExtCon' function which eliminates a 'NoExtCon', much like 'Data.Void.absurd' eliminates a 'Void'. I also renamed the existing `NoExt` type to `NoExtField` to better distinguish it from `NoExtCon`. Unsurprisingly, there is a lot of code churn resulting from this. Bumps the Haddock submodule. Fixes #15247. - - - - - b05c8423 by Phuong Trinh at 2019-07-09T22:55:41-04:00 Fix #16511: changes in interface dependencies should trigger recompilation If the union of dependencies of imported modules change, the `mi_deps` field of the interface files should change as well. Because of that, we need to check for changes in this in recompilation checker which we are not doing right now. This adds a checks for that. - - - - - fb43bddc by John Ericson at 2019-07-09T22:56:18-04:00 Fix two more `#ifndef` for the linter - - - - - 0472f0f6 by John Ericson at 2019-07-09T22:56:18-04:00 Remove most uses of TARGET platform macros These prevent multi-target builds. They were gotten rid of in 3 ways: 1. In the compiler itself, replacing `#if` with runtime `if`. In these cases, we care about the target platform still, but the target platform is dynamic so we must delay the elimination to run time. 2. In the compiler itself, replacing `TARGET` with `HOST`. There was just one bit of this, in some code splitting strings representing lists of paths. These paths are used by GHC itself, and not by the compiled binary. (They are compiler lookup paths, rather than RPATHS or something that does matter to the compiled binary, and thus would legitamentally be target-sensative.) As such, the path-splitting method only depends on where GHC runs and not where code it produces runs. This should have been `HOST` all along. 3. Changing the RTS. The RTS doesn't care about the target platform, full stop. 4. `includes/stg/HaskellMachRegs.h` This file is also included in the genapply executable. This is tricky because the RTS's host platform really is that utility's target platform. so that utility really really isn't multi-target either. But at least it isn't an installed part of GHC, but just a one-off tool when building the RTS. Lying with the `HOST` to a one-off program (genapply) that isn't installed doesn't seem so bad. It's certainly better than the other way around of lying to the RTS though not to genapply. The RTS is more important, and it is installed, *and* this header is installed as part of the RTS. - - - - - 24782b89 by John Ericson at 2019-07-09T22:56:18-04:00 Deduplicate "unique subdir" code between GHC and Cabal The code, including the generated module with the version, is now in ghc-boot. Config.hs reexports stuff as needed, ghc-pkg doesn't need any tricks at all. - - - - - 42ff8653 by Ben Gamari at 2019-07-09T22:56:53-04:00 testsuite: Fix #16818 Renames performance metrics to include whether they are compile-time or runtime metrics. - - - - - 18ac9ad4 by Alp Mestanogullari at 2019-07-09T22:57:31-04:00 Hadrian: implement key-value settings for builder options They take the general form `foo.bar.baz [+]= some values`, where `=` completely overrides the arguments for a builder and `+=` extends them. We currenly only support settings for updating the GHC and C compiler options, of the form: ``` {stage0, ..., stage3 or *}.{package name or *} .ghc.{c, hs, link, deps, toolargs or *}.opts {stage0, ..., stage3 or *}.{package name or *} .cc.{c, deps or *}.opts ``` The supported settings and their use is covered in the new section of `hadrian/doc/user-settings.md`, while the implementation is explained in a new Note [Hadrian settings]. Most of the logic is implemented in a new module, `Settings.Parser`, which contains key-value assignment/extension parsers as well as utilities for specifying allowed settings at a high-level, generating a `Predicate` from such a description or generating the list of possible completions for a given string. The additions to the `Settings` module make use of this to describe the settings that Hadrian currently supports, and apply all such key-value settings (from the command line and `<root>/hadrian.settings`) to the flavour that Hadrian is going to proceed with. This new setting system comes with support for generating Bash completions, implemented in `hadrian/completion.sh` and Hadrian's `autocomplete` target: > source hadrian/completion.sh > hadrian/build.sh stage1.base.ghc.<TAB> stage1.base.ghc.c.opts stage1.base.ghc.hs.opts stage1.base.ghc.*.opts stage1.base.ghc.deps.opts stage1.base.ghc.link.opts stage1.base.ghc.toolargs.opts - - - - - 7f8bf98e by Alp Mestanogullari at 2019-07-09T22:58:09-04:00 Hadrian: fix source-dist rule The first problem was that the list of files/dirs to embed or ignore was not up-to-date. The second problem was that the 'Cwd' option used when running the Tar builder in the source-dist rule didn't actually change the current directory and was therefore failing. Finally, the source-dist rule did not pre-generate Haskell modules derived from .x (alex) and .y (happy) files, like the Make build system does -- this is now fixed. We might be doing too much work for that last step (we seem to be building many things until we get to generating the source distribution), but extracting the distribution and running ./configure && hadrian/build.sh --flavour=quickest -j from there does work for me now. - - - - - d7423f10 by Ömer Sinan Ağacan at 2019-07-09T22:58:48-04:00 Testsuite tweaks and refactoring - Rename requires_th to req_th for consistency with other req functions (e.g. req_interp, req_profiling etc.) - req_th (previously requires_th) now checks for interpreter (via req_interp). With this running TH tests are skipped when running the test suite with stage=1. - Test tweaks: - T9360a, T9360b: Use req_interp - recomp009, T13938, RAE_T32a: Use req_th - Fix check-makefiles linter: it now looks for Makefiles instead of .T files (which are actually Python files) - - - - - 897a59a5 by Ömer Sinan Ağacan at 2019-07-09T22:59:26-04:00 Minor refactoring in CoreSimpl When `join_ids` is empty `extendVarSetList existing_joins join_ids` is already no-op, so no need to check whether `join_ids` is empty or not before extending the joins set. - - - - - 85da17e5 by Eric Wolf at 2019-07-09T23:00:03-04:00 Add testcase T16804 for #16804 slightly larger testcase for :type-at and :uses so we can see changes, if #16804 is done. - - - - - 8fcc931c by Eric Wolf at 2019-07-09T23:00:03-04:00 T16804: adjust src spans - - - - - a35e0916 by Ben Gamari at 2019-07-09T23:00:42-04:00 hadrian/doc: Add some discussion of compilation stages This documents some of the lore surrounding the nature and naming of GHC's stage numbers. - - - - - d2e290d3 by Simon Peyton Jones at 2019-07-09T23:01:24-04:00 Fix erroneous float in CoreOpt The simple optimiser was making an invalid transformation to join points -- yikes. The fix is easy. I also added some documentation about the fact that GHC uses a slightly more restrictive version of join points than does the paper. Fix #16918 - - - - - cb5271ac by Kevin Buhr at 2019-07-11T17:46:19-04:00 Add regression test for old panic on inlining undeclared identifier (#495) - - - - - 01ec8549 by Andreas Klebinger at 2019-07-11T17:46:57-04:00 Special case a few common patterns in unionLists. In particular we very often pass one empty list and in these cases we want to avoid the overhead of computing `xs ++ []`. This should fix #14759 and #16911. - - - - - b507aceb by Ryan Scott at 2019-07-11T17:47:41-04:00 Don't typecheck too much (or too little) in DerivingVia (#16923) Previously, GHC would typecheck the `via` type once per class in a `deriving` clause, which caused the problems observed in #16923. This patch restructures some of the functionality in `TcDeriv` and `TcHsType` to avoid this problem. We now typecheck the `via` type exactly once per `deriving` clause and *then* typecheck all of the classes in the clause. See `Note [Don't typecheck too much in DerivingVia]` in `TcDeriv` for the full details. - - - - - 8449c5b6 by nineonine at 2019-07-11T17:48:18-04:00 Allow reusing temporary object files generated by GHCi by writing to -odir in case -fwrite-interface was specified (#16670) - - - - - d5c899d1 by Ben Gamari at 2019-07-11T17:48:54-04:00 head.hackage: Run build on head.hackage's master branch The GitLab CI infrastructure is now in the master branch. - - - - - 8a209384 by Ben Gamari at 2019-07-11T17:48:54-04:00 head.hackage: Run builds with -dcore-lint - - - - - e4c73514 by Simon Peyton Jones at 2019-07-12T02:20:01-04:00 Fix kind-checking for data/newtypes In one spot in kcConDecl we were passing in the return kind signature rether than the return kind. e.g. #16828 newtype instance Foo :: Type -> Type where MkFoo :: a -> Foo a We were giving kcConDecl the kind (Type -> Type), whereas it was expecting the ultimate return kind, namely Type. This "looking past arrows" was being done, independently, in several places, but we'd missed one. This patch moves it all to one place -- the new function kcConDecls (note the plural). I also took the opportunity to rename tcDataFamHeader to tcDataFamInstHeader (The previous name was consistently a source of confusion.) - - - - - de3935a6 by Shayne Fletcher at 2019-07-12T02:20:43-04:00 Add shake 0.18.3 to extra deps - - - - - a31b24a5 by Ashley Yakeley at 2019-07-13T16:35:41-04:00 base: Data.Fixed: make HasResolution poly-kinded (#10055, #15622) - - - - - 688a1b89 by Alp Mestanogullari at 2019-07-13T16:36:18-04:00 compiler: trace SysTools commands to emit start/stop eventlog markers This patch was motivated by some performance characterization work done for #16822, where we suspected that GHC was spending a lot of time waiting on the linker to be done. (That turned out to be true.) The tracing is taken care of by ErrUtils.withTiming, so this patch just defines and uses a little wrapper around that function in all the helpers for calling the various systools (C compiler, linker, unlit, ...). With this patch, assuming a GHC executable linked against an eventlog-capable RTS (RTS ways that contain the debug, profiling or eventlog way units), we can measure how much time is spent in each of the SysTools when building hello.hs by simply doing: ghc hello.hs -ddump-timings +RTS -l The event names are "systool:{cc, linker, as, unlit, ...}". - - - - - 348cc8eb by Andreas Klebinger at 2019-07-13T16:36:57-04:00 Add two CmmSwitch optimizations. Move switch expressions into a local variable when generating switches. This avoids duplicating the expression if we translate the switch to a tree search. This fixes #16933. Further we now check if all branches of a switch have the same destination, replacing the switch with a direct branch if that is the case. Both of these patterns appear in the ENTER macro used by the RTS but are unlikely to occur in intermediate Cmm generated by GHC. Nofib result summary: -------------------------------------------------------------------------------- Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- Min -0.0% -0.0% -15.7% -15.6% 0.0% Max -0.0% 0.0% +5.4% +5.5% 0.0% Geometric Mean -0.0% -0.0% -1.0% -1.0% -0.0% Compiler allocations go up slightly: +0.2% Example output before and after the change taken from RTS code below. All but one of the memory loads `I32[_c3::I64 - 8]` are eliminated. Instead the data is loaded once from memory in block c6. Also the switch in block `ud` in the original code has been eliminated completely. Cmm without this commit: ``` stg_ap_0_fast() { // [R1] { [] } {offset ca: _c1::P64 = R1; // CmmAssign goto c2; // CmmBranch c2: if (_c1::P64 & 7 != 0) goto c4; else goto c6; c6: _c3::I64 = I64[_c1::P64]; if (I32[_c3::I64 - 8] < 26 :: W32) goto ub; else goto ug; ub: if (I32[_c3::I64 - 8] < 15 :: W32) goto uc; else goto ue; uc: if (I32[_c3::I64 - 8] < 8 :: W32) goto c7; else goto ud; ud: switch [8 .. 14] (%MO_SS_Conv_W32_W64(I32[_c3::I64 - 8])) { case 8, 9, 10, 11, 12, 13, 14 : goto c4; } ue: if (I32[_c3::I64 - 8] >= 25 :: W32) goto c4; else goto uf; uf: if (%MO_SS_Conv_W32_W64(I32[_c3::I64 - 8]) != 23) goto c7; else goto c4; c4: R1 = _c1::P64; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; ug: if (I32[_c3::I64 - 8] < 28 :: W32) goto uh; else goto ui; uh: if (I32[_c3::I64 - 8] < 27 :: W32) goto c7; else goto c8; ui: if (I32[_c3::I64 - 8] < 29 :: W32) goto c8; else goto c7; c8: _c1::P64 = P64[_c1::P64 + 8]; goto c2; c7: R1 = _c1::P64; call (_c3::I64)(R1) args: 8, res: 0, upd: 8; } } ``` Cmm with this commit: ``` stg_ap_0_fast() { // [R1] { [] } {offset ca: _c1::P64 = R1; goto c2; c2: if (_c1::P64 & 7 != 0) goto c4; else goto c6; c6: _c3::I64 = I64[_c1::P64]; _ub::I64 = %MO_SS_Conv_W32_W64(I32[_c3::I64 - 8]); if (_ub::I64 < 26) goto uc; else goto uh; uc: if (_ub::I64 < 15) goto ud; else goto uf; ud: if (_ub::I64 < 8) goto c7; else goto c4; uf: if (_ub::I64 >= 25) goto c4; else goto ug; ug: if (_ub::I64 != 23) goto c7; else goto c4; c4: R1 = _c1::P64; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; uh: if (_ub::I64 < 28) goto ui; else goto uj; ui: if (_ub::I64 < 27) goto c7; else goto c8; uj: if (_ub::I64 < 29) goto c8; else goto c7; c8: _c1::P64 = P64[_c1::P64 + 8]; goto c2; c7: R1 = _c1::P64; call (_c3::I64)(R1) args: 8, res: 0, upd: 8; } } ``` - - - - - 232002c4 by James Foster at 2019-07-13T16:37:34-04:00 Make HsInstances and DynFlags compile with -O0 for Stage0 to speed up Hadrian builds (fixes #16936) - - - - - a7176fa1 by Ömer Sinan Ağacan at 2019-07-13T16:38:13-04:00 Minor refactoring in CmmBuildInfoTables - Replace `catMaybes (map ...)` with `mapMaybe ...` - Remove a list->set->list conversion - - - - - ff04eb59 by John Ericson at 2019-07-14T01:19:22-04:00 Remove purely external primops The compiler doesn't create uses nor compiles the uses that exist specially. These are just plain C-- FFI. These `await*` ones are especially important to so convert because "true" primops are hard to make platform-specific currently. The other exports are part of this commit so this module always exports something, which avoids silly CPP elsewhere. More will be added later once `foreign import prim` is extended. - - - - - f9b00038 by Matthew Pickering at 2019-07-14T01:19:58-04:00 hadrian: Build debug rts with -O0 -g3 and disable rts stripping Fixes #16920 - - - - - f508b7ce by Ben Gamari at 2019-07-14T01:20:34-04:00 Don't package settings in bindist Since !712 the `settings` file is produced by the build system instead of autoconf. However, this introduced a subtle bug where we would fail to rebuild the `settings` file with what we have learned from the install-time `configure` invocation. Fix this by not packaging `settings` in the bindist tarball. The build system will take care of the rest. Also fix a bug where the value of `UseLibdw` was not being persisted to the install time `configure`. - - - - - e7ed53c9 by John Ericson at 2019-07-14T01:21:11-04:00 Remove LLVM_TARGET platform macros Instead following @angerman's suggestion put them in the config file. Maybe we could re-key llvm-targets someday, but this is good for now. - - - - - bd9fc1b2 by John Ericson at 2019-07-14T01:21:48-04:00 Make CPP linter skip certain files - docs which document the lint and need to contain the unutterable - vendored code which is outside our purview - - - - - d7c6c471 by John Ericson at 2019-07-14T01:21:48-04:00 Expunge #ifdef and #ifndef from the codebase These are unexploded minds as far as the linter is concerned. I don't want to hit in my MRs by mistake! I did this with `sed`, and then rolled back some changes in the docs, config.guess, and the linter itself. - - - - - fce8f240 by xplorld at 2019-07-14T08:32:48-04:00 rename type parameter in `instance Applicative ((->) a)`, fixing #16928 - - - - - 78ed46f3 by Niklas Hambüchen at 2019-07-14T08:33:26-04:00 primops: haddock: Fix typo in referenced function. Found by @lehins. - - - - - a39a3cd6 by Ben Gamari at 2019-07-15T00:14:40-04:00 gitlab-ci: Disable submodule linter for now - - - - - 0670f98a by Arnaud Spiwack at 2019-07-15T09:23:15+02:00 Add a note in the simplifier about in-scope set as a substitution See also the discussion at #16592 - - - - - 284a2f44 by Vladislav Zavialov at 2019-07-15T18:29:05-04:00 Decouple AddAnn from P - - - - - 1befd2c0 by Vladislav Zavialov at 2019-07-15T18:29:05-04:00 PV is not P (#16611) - - - - - 5728d9fa by Artem Pelenitsyn at 2019-07-16T02:40:08-04:00 Sort out Hadrian colored output flags (fix #16397) Hadrian used to have a separate flag --progress-colour to control colored output during the build. After introduction of a Shake flag with similar purpose Hadrian's flag became redundant. The commit removes --progress-colour and switches to Shake's flag. The only difference between the two is that Hadrian has special default mode when it tries to determine if the terminal support colored output. The user can override it using (Shake's) `--[no-]color`. - - - - - db948dae by Ben Gamari at 2019-07-16T02:40:43-04:00 Revert "Add support for SIMD operations in the NCG" Unfortunately this will require more work; register allocation is quite broken. This reverts commit acd795583625401c5554f8e04ec7efca18814011. - - - - - 373c9cb3 by Daniel Gröber at 2019-07-16T02:41:23-04:00 rts: Divorce init of Heap profiler from CCS profiler Currently initProfiling gets defined by Profiling.c only if PROFILING is defined. Otherwise the ProfHeap.c defines it. This is just needlessly complicated so in this commit I make Profiling and ProfHeap into properly seperate modules and call their respective init functions from RtsStartup.c. - - - - - 52f755aa by Daniel Gröber at 2019-07-16T02:41:23-04:00 rts: Rename the nondescript initProfiling2 to refreshProfilingCCSs - - - - - 0a9b77b8 by John Ericson at 2019-07-17T12:20:26-04:00 Create {Int,Word}32Rep This prepares the way for making Int32# and Word32# the actual size they claim to be. Updates binary submodule for (de)serializing the new runtime reps. - - - - - 8add024f by Sebastian Graf at 2019-07-17T12:20:27-04:00 Make GHC-in-GHCi work on Windows By not building anything in the dynamic way on Windows, where we don't have a working story for DLLs yet. Also the ghcid command needs to call bash on the hadrian/ghci.sh script explicitly as the path gets interpreted differently otherwise. - - - - - d48da6ff by Ben Gamari at 2019-07-18T20:55:11-04:00 gitlab-ci: Run slow validate in -debug job Otherwise we don't compile the stage2 compiler with DEBUG, meaning the testsuite isn't checked with assertions. Metric Increase: haddock.Cabal - - - - - 272246bf by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: More type checking fixes - - - - - c7bcd017 by Ben Gamari at 2019-07-18T20:55:11-04:00 Add HasDebugCallStack to unionLists This should help identify a few cases where this is throwing warnings - - - - - 3cec2af6 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Mark static-plugins as broken in profiled ways See #16803. - - - - - e8adffb5 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Set -dinitial-unique when reversing uniques Otherwise the unique counter starts at 0, causing us to immediately underflow. - - - - - b9e9d8c9 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Fix req_th - - - - - d238d306 by Ben Gamari at 2019-07-18T20:55:11-04:00 Fix formatting of --info's "Debug on" field As noted in #16914, the value `True` was used instead of `YES` here, in contrast to the other boolean fields emitted by `--info`. This confused the testsuite driver and broke the `ghc_debugged` testsuite predicate. - - - - - eb8c40e3 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Mark hWaitForInput-accurate-stdin as broken in all threaded ways Previously it was not marked as broken in profthreaded - - - - - b16cabc1 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Print output from hp2ps - - - - - b62a2dfb by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Fix some ints used as bools - - - - - b3df1efb by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Skip forking tests in profiled ways As noted in #11645 and #8862, forking and profiling don't go well together. Bumps hpc and unix submodules. - - - - - 49dcbf86 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Mark test-hole-plugin as req_th This requires code loading and therefore can't be run in the profiled ways when GHC is dynamically linked. - - - - - ce8ffd80 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Unmark recomp007 as broken Fixed in #14759. - - - - - 82abc479 by Ben Gamari at 2019-07-18T20:55:11-04:00 testsuite: Mark T4808 as broken in threaded2 way As noted in #16909. - - - - - 73703d9b by Artem Pelenitsyn at 2019-07-19T18:06:22-04:00 Hide "Loading package environment" message with -v0 (fix #16879) - - - - - 9372ff92 by Vladislav Zavialov at 2019-07-19T18:06:57-04:00 Drop the orphan roles check (#16941) 9366e019 introduced a check for orphan roles to fix #8485 6ab5da99 changed the lookup code and made the check redundant. Now it is removed. - - - - - 69adb253 by Richard Eisenberg at 2019-07-19T18:07:37-04:00 Fix #16870 by improving documentation (only) - - - - - f1980a1e by Sebastian Graf at 2019-07-19T18:08:15-04:00 Make generated ghc-stage<n> scripts executable - - - - - bec17997 by James Foster at 2019-07-19T18:08:51-04:00 users-guide: corrected -fmax-relevant-binds reverse to be -fno-max-relevant-binds - - - - - 257d1fd8 by Ryan Scott at 2019-07-19T18:09:28-04:00 Don't maintainer-clean libraries/ghc-boot/ghc.mk (#16953) This makes the `maintainer-clean` rule in `ghc.mk` slightly more sophisticated so that it does not remove the version-controlled file `libraries/ghc-boot/ghc.mk`, which was checked into version control in commit 24782b89907ab36fb5aef3a17584f4c10f1e2690. Fixes #16953. - - - - - ff996555 by Richard Eisenberg at 2019-07-19T18:10:06-04:00 Add module doc for Plugins. This was requested in #15650. - - - - - 08ad7ef4 by Baldur Blöndal at 2019-07-20T07:51:22-04:00 Added do-notation examples for Functor, Applicative and Monad combinators. - - - - - 7b42ece5 by Alfredo Di Napoli at 2019-07-20T07:52:01-04:00 Line wrap when pp long expressions (fixes #16874) This commit fixes #16874 by using `fsep` rather than `sep` when pretty printing long patterns and expressions. - - - - - 3676375f by Andreas Klebinger at 2019-07-20T07:52:39-04:00 Bump nofib submodule. - - - - - 4dfd6a5f by Matthew Pickering at 2019-07-20T07:53:15-04:00 hadrian: Remove RTS -Waggregate-return warning This was removed from make in 077b92fa39839a8e83cd87398435424403cf6486 - - - - - 5042ba9d by Andreas Klebinger at 2019-07-21T05:03:04-04:00 Expose the GhcPrelude module. This makes it simpler to load Modules importing it when using ghc-the-package. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 67ee741b by Ivan Kasatenko at 2019-07-21T05:03:40-04:00 Do not ignore events deletion when events to be added are provided (#16916) Kqueue/kevent implementation used to ignore events to be unsubscribed from when events to be subscribed to were provided. This resulted in a lost notification subscription, when GHC runtime didn't listen for any events, yet the kernel considered otherwise and kept waking up the IO manager thread. This commit fixes this issue by always adding and removing all of the provided subscriptions. - - - - - 32be4461 by Roland Senn at 2019-07-21T05:04:17-04:00 Fix #8487: Debugger confuses variables To display the free variables for a single breakpoint, GHCi pulls out the information from the fields `modBreaks_breakInfo` and `modBreaks_vars` of the `ModBreaks` data structure. For a specific breakpoint this gives 2 lists of types 'Id` (`Var`) and `OccName`. They are used to create the Id's for the free variables and must be kept in sync: If we remove an element from the Names list, then we also must remove the corresponding element from the OccNames list. - - - - - 4854a349 by Ben Gamari at 2019-07-21T05:04:53-04:00 ghc-cabal: Use fromFlagOrDefault instead of fromFlag As fromFlag is partial. The only case where we used fromFlag is when determining whether to strip libraries; we now assume that we shouldn't. - - - - - 4c7a8462 by Xavier Denis at 2019-07-23T11:43:59-04:00 Make sure to load interfaces when running :instances - - - - - f9af30f8 by Ömer Sinan Ağacan at 2019-07-23T11:44:38-04:00 Remove fix-submodules.py Now that we have absolute paths for submodules (since a76b233d) we no longer need this script. - - - - - 6ade71fb by Alp Mestanogullari at 2019-07-23T23:06:36-04:00 Hadrian: run the testsuite in Windows CI job Since MR !1025 fixed the Windows build, allowing us to build a binary distribution, we can now run the testsuite in that CI job. This required fixing 'createFileLink': it should not try to create symlinks on Windows (that requires admin priviledges, which Hadrian can't assume). We now instead fall back to copying. This patch also removes some duplicated logic for iserv in the test rules, where we handle our dependency on the iserv binaries in a special way. - - - - - 3dbcc368 by Richard Eisenberg at 2019-07-23T23:07:13-04:00 Simon and I like to work in hsSyn, too. - - - - - b95b6380 by John Ericson at 2019-07-24T16:49:53-04:00 Make stage 1 GHC target independent Now that the target macros are not being used, we remove them. This prevents target hardcoding regressions. - - - - - d0f8ed20 by Ben Gamari at 2019-07-24T16:50:28-04:00 gitlab-ci: Fix source tarball job * Use show! in source tarball job. Since we aren't actually building anything in this job `show` won't work. * Fix Docker image name * Make `version` file contain only version string - - - - - 90dd2ea0 by Vladislav Zavialov at 2019-07-24T23:11:22-04:00 ASSERT(vis_flag==ForallInvis) in hsScopedTvs - - - - - e07f0e2b by Vladislav Zavialov at 2019-07-24T23:11:57-04:00 Drop unused helpers 'mkTyClGroup' and 'emptyTyClGroup' - - - - - cb495b3c by Ryan Scott at 2019-07-25T17:25:26-04:00 Make DefUses = OrdList DefUse Before, `type DefUses = [DefUse]`. But lists are a terrible choice of data structure here, as we frequently append to the right of a `DefUses`, which yields some displeasing asymptotics. Let's instead use `OrdList`, which has constant-time appending to the right. This is one step on the way to #10347. - - - - - b9c99df1 by Ömer Sinan Ağacan at 2019-07-25T17:26:03-04:00 Printer: add an empty line between bindings in Rec STG binding groups Before: Rec { x2_r10T :: Lib.Bar [GblId, Unf=OtherCon []] = CCS_DONT_CARE Lib.Bar! [x3_r10U]; x3_r10U :: Lib.Foo [GblId, Unf=OtherCon []] = CCS_DONT_CARE Lib.Foo! [x1_r10p x2_r10T]; end Rec } After: Rec { x2_r10T :: Lib.Bar [GblId, Unf=OtherCon []] = CCS_DONT_CARE Lib.Bar! [x3_r10U]; x3_r10U :: Lib.Foo [GblId, Unf=OtherCon []] = CCS_DONT_CARE Lib.Foo! [x1_r10p x2_r10T]; end Rec } - - - - - 30b6f391 by Ryan Scott at 2019-07-26T00:57:02-04:00 Banish reportFloatingViaTvs to the shadow realm (#15831, #16181) GHC used to reject programs of this form: ``` newtype Age = MkAge Int deriving Eq via Const Int a ``` That's because an earlier implementation of `DerivingVia` would generate the following instance: ``` instance Eq Age where (==) = coerce @(Const Int a -> Const Int a -> Bool) @(Age -> Age -> Bool) (==) ``` Note that the `a` in `Const Int a` is not bound anywhere, which causes all sorts of issues. I figured that no one would ever want to write code like this anyway, so I simply banned "floating" `via` type variables like `a`, checking for their presence in the aptly named `reportFloatingViaTvs` function. `reportFloatingViaTvs` ended up being implemented in a subtly incorrect way, as #15831 demonstrates. Following counsel with the sage of gold fire, I decided to abandon `reportFloatingViaTvs` entirely and opt for a different approach that would _accept_ the instance above. This is because GHC now generates this instance instead: ``` instance forall a. Eq Age where (==) = coerce @(Const Int a -> Const Int a -> Bool) @(Age -> Age -> Bool) (==) ``` Notice that we now explicitly quantify the `a` in `instance forall a. Eq Age`, so everything is peachy scoping-wise. See `Note [Floating `via` type variables]` in `TcDeriv` for the full scoop. A pleasant benefit of this refactoring is that it made it much easier to catch the problem observed in #16181, so this patch fixes that issue too. Fixes #15831. Fixes #16181. - - - - - aae0457f by nineonine at 2019-07-26T00:57:39-04:00 Change behaviour of -ddump-cmm-verbose to dump each Cmm pass output to a separate file and add -ddump-cmm-verbose-by-proc to keep old behaviour (#16930) - - - - - 00d9d284 by Vladislav Zavialov at 2019-07-26T00:58:15-04:00 TemplateHaskell: reifyType (#16976) - - - - - ea08fa37 by Vladislav Zavialov at 2019-07-26T00:58:15-04:00 reifyTypeOfThing: panic on impossible cases - - - - - 7c9fb2f0 by Adam Sandberg Eriksson at 2019-07-26T09:49:14-04:00 ghc-heap: implement WEAK closure type #16974 - - - - - 26314386 by nineonine at 2019-07-26T09:49:51-04:00 Add regression test for #16946 - - - - - cd11f81f by Fumiaki Kinoshita at 2019-07-28T19:47:50-04:00 base: add Functor, Applicative, Monad, Alternative, MonadPlus, Generic and Generic1 instances to Kleisli - - - - - c1a06d49 by Dale Wijnand at 2019-07-28T19:48:27-04:00 hadrian: relink to the flavours doc in the ghc repo - - - - - 9f8cdb35 by Richard Eisenberg at 2019-07-29T19:32:16-04:00 Add Note [RuntimeRep and PrimRep] in RepType Also adds Note [Getting from RuntimeRep to PrimRep], which deocuments a related thorny process. This Note addresses #16964, which correctly observes that documentation for this thorny design is lacking. Documentation only. - - - - - 86f47b8e by Dale Wijnand at 2019-07-29T19:32:52-04:00 hadrian: Drop a stale limitation tracking issue https://github.com/snowleopard/hadrian/issues/187 was superseded by https://github.com/snowleopard/hadrian/issues/669, which has also been closed. So, optimistically, dropping this as a limitation issue. - - - - - 9c8a211a by Andreas Klebinger at 2019-07-30T01:33:50-04:00 Expand the preallocated Int range to [-16,255] Effects as I measured them: RTS Size: +0.1% Compile times: -0.5% Runtine nofib: -1.1% Nofib runtime result seems to mostly come from the `CS` benchmark which is very sensible to alignment changes so this is likely over represented. However the compile time changes are realistic. This is related to #16961. - - - - - 2829f6da by Simon Peyton Jones at 2019-07-30T01:34:27-04:00 Apply a missing substitution in mkEtaWW (#16979) The `mkEtaWW` case for newtypes forgot to apply the substitution to the newtype coercion, resulting in the Core Lint errors observed in #16979. Easily fixed. Fixes #16979. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 371dadfb by Ben Gamari at 2019-07-31T04:27:59-04:00 Break up TyCoRep This breaks up the monstrous TyCoReps module into several new modules by topic: * TyCoRep: Contains the `Coercion`, `Type`, and related type definitions and a few simple predicates but nothing further * TyCoPpr: Contains the the pretty-printer logic * TyCoFVs: Contains the free variable computations (and `tyConAppNeedsKindSig`, although I suspect this should change) * TyCoSubst: Contains the substitution logic for types and coercions * TyCoTidy: Contains the tidying logic for types While we are able to eliminate a good number of `SOURCE` imports (and make a few others smaller) with this change, we must introduce one new `hs-boot` file for `TyCoPpr` so that `TyCoRep` can define `Outputable` instances for the types it defines. Metric Increase: haddock.Cabal haddock.compiler - - - - - b6fa7fe3 by Ben Gamari at 2019-07-31T04:27:59-04:00 gitignore: Add .mypy_cache - - - - - 88410e77 by Ben Gamari at 2019-07-31T04:27:59-04:00 Move tyConAppNeedsKindSig to Type Previously it was awkwardly in TyCoFVs (and before that in TyCoRep). Type seems like a sensible place for it to live. - - - - - 787fab43 by Ben Gamari at 2019-07-31T04:27:59-04:00 Work around redundant import issue As mentioned in #16997, GHC currently complains about this import. In general I'm reluctant to paper over things like this but in the case of an hs-boot file I think adding an import list is the right thing to do regardless of the bug. - - - - - 5e04841c by Ben Gamari at 2019-07-31T13:53:58-04:00 gitlab-ci: Fix it after upgrade It seems that the regular expression parser changed in GitLab 12.1 and now does now support forward slashes in the RE, even when escaped. - - - - - 986643cb by Ivan Kasatenko at 2019-08-01T13:49:50-04:00 Fix T16916 CI failures (#16966) 1. Slightly increased the waiting time for the tested effect to be more profound. 2. Introduced measuring of the actual time spent waiting and adjusing CPU time by it to compensate for threadDelay waiting time inconsistencies. - - - - - 95521140 by Andreas Klebinger at 2019-08-02T08:14:10-04:00 Add StandaloneDeriving example for DerivingVia. [skip-ci] - - - - - 1b9d32b8 by Ryan Scott at 2019-08-02T08:14:47-04:00 Rip out 9-year-old pattern variable hack (#17007) GHC had an ad hoc validity check in place to rule out pattern variables bound by type synonyms, such as in the following example: ```hs type ItemColID a b = Int -- Discards a,b get :: ItemColID a b -> ItemColID a b get (x :: ItemColID a b) = x :: ItemColID a b ``` This hack is wholly unnecessary nowadays, since OutsideIn(X) is more than capable of instantiating `a` and `b` to `Any`. In light of this, let's rip out this validity check. Fixes #17007. - - - - - 93bed40a by Ryan Scott at 2019-08-02T08:15:25-04:00 Use injectiveVarsOfType to catch dodgy type family instance binders (#17008) Previously, we detected dodgy type family instances binders by expanding type synonyms (via `exactTyCoVarsOfType`) and looking for type variables on the RHS that weren't mentioned on the (expanded) LHS. But this doesn't account for type families (like the example in #17008), so we instead use `injectiveVarsOfType` to only count LHS type variables that are in injective positions. That way, the `a` in `type instance F (x :: T a) = a` will not count if `T` is a type synonym _or_ a type family. Along the way, I moved `exactTyCoVarsOfType` to `TyCoFVs` to live alongside its sibling functions that also compute free variables. Fixes #17008. - - - - - c902f56b by Krzysztof Gogolewski at 2019-08-02T08:16:03-04:00 Remove build.nix.sh This file refers to shell.nix, which was removed in 430e6fedfda and c00d2f59d. - - - - - 5e960287 by Adam Sandberg Eriksson at 2019-08-02T08:16:45-04:00 docs: fixs -prof links in rts-flags section - - - - - 0c5cd771 by Alp Mestanogullari at 2019-08-02T22:20:14-04:00 compiler: emit finer grained codegen events to eventlog - - - - - 0ecacb1e by Alp Mestanogullari at 2019-08-02T22:20:14-04:00 Add Note [withTiming] in compiler/main/ErrUtils.hs - - - - - 4664bafc by Ben Gamari at 2019-08-02T22:20:50-04:00 rts: Always truncate output files Previously there were numerous places in the RTS where we would fopen with the "w" flag string. This is wrong as it will not truncate the file. Consequently if we write less data than the previous length of the file we will leave garbage at its end. Fixes #16993. - - - - - e3cbe319 by Ben Gamari at 2019-08-02T22:21:26-04:00 Packages: Add timing for package database initialization - - - - - a5227080 by Alp Mestanogullari at 2019-08-02T22:22:06-04:00 Hadrian: make settings, platformConstants, etc dependencies of lib:ghc This fixes #17003, where a user directly asked for the 'docs-haddock' target without building a complete stage 2 GHC first. Since haddock only depends on lib:ghc, the stage 2 GHC executable wasn't built, and neither were the settings, platformConstants, llvm-passes and llvm-targets files, since they are declared to be dependencies of exe:ghc. This makes sense in general since all GHC API users (haddock is one) will likely want those files to be there. - - - - - 7e404afd by Ben Gamari at 2019-08-04T18:16:51-04:00 gitlab-ci: Manually set SPHINXBUILD on Windows For some reason configure seems unable to find it on its own. Let's try giving it a hint. Addresses #16398. - - - - - 8a061d18 by Matthew Pickering at 2019-08-04T18:17:28-04:00 Update .gitignore Add some files generated by hadrian and some tooling files - - - - - 7d8d0012 by Simon Peyton Jones at 2019-08-04T18:18:08-04:00 Don't float unlifted join points to top level Ticket #16978 showed that we were floating a recursive, unlifted join point to top level. It's very much a corner case: joinrec j :: Int# j = jump j in ... But somehow it showed up in a real program. For non-recursive bindings in SetLevels.lvlBind we were already (correctly) checking for unlifted bindings, but when I wrote that code I didn't think that a /recursive/ binding could be unlifted but /join-points/ can be! Actually I don't think that SetLevels should be floating join points at all. SetLevels really floats things to move stuff out of loops and save allocation; but none of that applies to join points. The only reason to float join points is in cases like join j1 x = join j2 y = ... in ... which we might want to swizzle to join j2 x y = ... in join j1 x = ... in ... because now j1 looks small and might be inlined away altogether. But this is a very local float perhaps better done in the simplifier. Still: this patch fixes the crash, and does so in a way that is harmless if/when we change our strategy for floating join points. - - - - - 3b31a94d by Ben Gamari at 2019-08-04T18:18:08-04:00 testsuite: Add testsuite for #16978 - - - - - 2e031806 by Ben Gamari at 2019-08-04T18:18:45-04:00 configure: Search for LLVM executables with two-number versions Fedora uses the naming llc-7.0 while Debian uses llc-7. Ensure that both are found. Fixes #16990. - - - - - 6e5dfcd2 by Ben Gamari at 2019-08-04T18:19:21-04:00 testsuite: Rework tracking of fragile tests Breaks fragile tests into two groups, allowing us to easily preserve stdout/stderr of failing fragile tests. - - - - - ea16f6cb by Simon Peyton Jones at 2019-08-06T20:24:41-04:00 Remove dead parameter from coreToStgApp - - - - - 0c1ccf3c by James Foster at 2019-08-06T20:25:18-04:00 hadrian: Refactor file patterns for future Shake changes (fixes #17005) Shake will be moving from its current implementation of ?== to one from System.FilePattern. Support for `//` is being dropped, leaving only `*` and `**` as special forms. This commit converts the existing file patterns in Hadrian to the new format. It also removes all occurances of <//> and changes the user-settings docs to remove references to // and add **. The conversion is as follows: - //a ==> **/a - a// ==> a/** - a//b ==> a/**/b - - - - - c83e39bf by Matthew Pickering at 2019-08-06T20:25:54-04:00 Remove old/broken(?) .ghci script I was attempting to load hadrian into ghci by using `cabal new-repl exe:hadrian` but it failed because it tried to use this `.ghci` configuration. I'm not sure who used this script but you should really use the new-repl method. - - - - - 6f116005 by Ömer Sinan Ağacan at 2019-08-06T20:26:32-04:00 Introduce a type for "platform word size", use it instead of Int We introduce a PlatformWordSize type and use it in platformWordSize field. This removes to panic/error calls called when platform word size is not 32 or 64. We now check for this when reading the platform config. - - - - - 2073745c by mniip at 2019-08-07T10:18:07-04:00 Add a -fprint-axiom-incomps option (#15546) Supply branch incomps when building an IfaceClosedSynFamilyTyCon `pprTyThing` now has access to incomps. This also causes them to be written out to .hi files, but that doesn't pose an issue other than a more faithful bijection between `tyThingToIfaceDecl` and `tcIfaceDecl`. The machinery for displaying axiom incomps was already present but not in use. Since this is now a thing that pops up in ghci's :info the format was modified to look like a haskell comment. Documentation and a test for the new feature included. Test Plan: T15546 Reviewers: simonpj, bgamari, goldfire Reviewed By: simonpj Subscribers: rwbarton, carter GHC Trac Issues: #15546 Differential Revision: https://phabricator.haskell.org/D5097 - - - - - bca79345 by mniip at 2019-08-07T10:18:07-04:00 Fix test - - - - - 3d32286d by mniip at 2019-08-07T10:18:07-04:00 Explicitly number equations when printing axiom incompatibilities - - - - - ca8efc49 by mniip at 2019-08-07T10:18:07-04:00 Fix documentation - - - - - 2c1b1ad7 by mniip at 2019-08-07T10:18:07-04:00 Fix test - - - - - 8e2fe575 by Zubin Duggal at 2019-08-07T10:18:44-04:00 Fix bug preventing information about patterns from being serialized in .hie files - - - - - f1d0e49f by Ben Gamari at 2019-08-07T10:19:21-04:00 testsuite: Add tests for #16943 - - - - - 83ca42de by Ben Gamari at 2019-08-07T10:19:21-04:00 Revert "Make scanr a good producer and consumer" This reverts commit 4e1dfc3767167dddd0e151a2df8305b12aa0f49c. Due to #16943. - - - - - 81860281 by Joachim Breitner at 2019-08-10T14:39:27-04:00 Consolidate `TablesNextToCode` and `GhcUnreigsterised` in configure (#15548) `TablesNextToCode` is now a substituted by configure, where it has the correct defaults and error handling. Nowhere else needs to duplicate that, though we may want the compiler to to guard against bogus settings files. I renamed it from `GhcEnableTablesNextToCode` to `TablesNextToCode` to: - Help me guard against any unfixed usages - Remove any lingering connotation that this flag needs to be combined with `GhcUnreigsterised`. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 422ffce0 by Ben Gamari at 2019-08-10T14:40:03-04:00 Add timing on loadInterface AndreasK recently mentioned that he thought that interface file loading may be a non-trivial cost. Let's measure. - - - - - 0424de2d by Ömer Sinan Ağacan at 2019-08-10T14:40:46-04:00 Add test for #16893 - - - - - 672cbab2 by Ömer Sinan Ağacan at 2019-08-10T14:41:26-04:00 Reformat comments in StgSyn This does not make any changes in the contents -- formatting only. Previously the comments were too noisy and I've always found it very hard to read. Hopefully it's easier to read now. - - - - - 328a0efa by Sebastian Graf at 2019-08-13T17:30:15-04:00 Add Foldable, Traversable instances for Uniq(D)FM The `UniqDFM` is deterministic, of course, while we provide an unsafe `NonDetUniqFM` wrapper for `UniqFM` to opt into nondeterministic instances. - - - - - b1d29c67 by Tamar Christina at 2019-08-13T17:30:50-04:00 Fix binary distribution - - - - - a38104b4 by Andreas Klebinger at 2019-08-14T16:55:42-04:00 Rework the Binary Integer instance. We used to serialise large integers as strings. Now they are serialized as a list of Bytes. This changes the size for a Integer in the higher 64bit range from 77 to 9 bytes when written to disk. The impact on the general case is small (<1% for interface files) as we don't use many Integers. But for code that uses many this should be a nice benefit. - - - - - aa4d8b07 by Andreas Klebinger at 2019-08-14T16:56:20-04:00 Use os.devnull instead of '/dev/null' in the testsuite driver. The later caused issues on windows by being translated into "\\dev\\null" and python then trying to open this non-existant file. So we now use os.devnull inside python and convert it to "/dev/null" when calling out to the shell, which is bound to run in a unix like environment. This fixes an issue a test producing unexpected stderr output failed with a framework failure instead of showing a diff of the output. - - - - - 6329c70a by Richard Eisenberg at 2019-08-14T17:47:25-04:00 GHCi supports not-necessarily-lifted join points Fixes #16509. See Note [Not-necessarily-lifted join points] in ByteCodeGen, which tells the full story. This commit also adds some comments and cleans some code in the byte-code generator, as I was exploring around trying to understand it. (This commit removes an old test -- this is really a GHCi problem, not a pattern-synonym problem.) test case: ghci/scripts/T16509 - - - - - ca71d551 by James Foster at 2019-08-15T12:01:43-04:00 Remove unused imports of the form 'import foo ()' (Fixes #17065) These kinds of imports are necessary in some cases such as importing instances of typeclasses or intentionally creating dependencies in the build system, but '-Wunused-imports' can't detect when they are no longer needed. This commit removes the unused ones currently in the code base (not including test files or submodules), with the hope that doing so may increase parallelism in the build system by removing unnecessary dependencies. - - - - - 95837c0f by Tobias Dammers at 2019-08-15T22:13:13-04:00 Add test cases for #16615 - - - - - 8d076841 by Tobias Dammers at 2019-08-15T22:13:13-04:00 Make add_info attach unfoldings (#16615) - - - - - 14208853 by Sylvain Henry at 2019-08-15T22:13:52-04:00 Cmm: constant folding `quotRem x 2^N` `quot` and `rem` are implemented efficiently when the second argument is a constant power of 2. This patch uses the same implementations for `quotRem` primop. - - - - - 47e16237 by Ömer Sinan Ağacan at 2019-08-15T22:14:31-04:00 Document types of LitNumbers, minor refactoring in Literal.hs - - - - - ac73c1b1 by Sylvain Henry at 2019-08-18T05:16:40-04:00 Faster exactLog2 Make `exactLog2` faster (use `countLeadingZeros` and Int32 bit-ops). On my Core i7-9700k Criterion reports ~50% speedup (from 16 to 8ns). - - - - - 1230d6f9 by Ömer Sinan Ağacan at 2019-08-18T05:17:20-04:00 Typo fix in CoreToStg - - - - - d0716279 by Ryan Scott at 2019-08-18T05:18:01-04:00 Fix #17067 by making data family type constructors actually injective `TcTyClsDecls.tcFamDecl1` was using `NotInjective` when creating data family type constructors, which is just plain wrong. This tweaks it to use `Injective` instead. Fixes #17067. - - - - - 993804bf by Sam Halliday at 2019-08-18T16:39:21-04:00 expose ModuleInfo.minf_rdr_env for tooling authors - - - - - 5b713aa3 by Ömer Sinan Ağacan at 2019-08-18T16:40:03-04:00 Fix COMPACT_NFDATA closure size, more CNF sanity checking We now do a shallow closure check on objects in compact regions. See the new comment on why we can't do a "normal" closure check. - - - - - ac7c738b by Richard Lupton at 2019-08-19T02:11:59-04:00 Generalized MonadUtils folds to Foldable (#16969) - - - - - 3a1efe1a by Richard Lupton at 2019-08-19T02:12:00-04:00 Re-export foldlM and foldrM from Data.Foldable in MonadUtils (#16969) - - - - - 2a394246 by Richard Lupton at 2019-08-19T02:12:00-04:00 Use Foldable instance of Bag for specialised Bag folds (#16969) - - - - - ac79dfe9 by Richard Lupton at 2019-08-19T02:12:00-04:00 Remove Bag fold specialisations (#16969) - - - - - 5e40356f by Ben Gamari at 2019-08-19T02:12:36-04:00 gitlab-ci: Update bootstrap compiled used for Darwin builds - - - - - d5055248 by Ben Gamari at 2019-08-22T09:25:08-04:00 gitlab-ci: Add Windows full build during the nightly pipeline - - - - - a33bad2d by Sylvain Henry at 2019-08-22T09:25:47-04:00 Doc: add Haddocks for quotRemWord2 primop - - - - - 605bce26 by James Foster at 2019-08-22T18:47:20-04:00 Add documentation for Hadrian expressions This commit adds documentation on Hadrian's 'Expr' type and references the documentation in hadrian/README.md - - - - - 8f32d2bc by TDecki at 2019-08-22T18:47:57-04:00 base: Reintroduce fusion for scanr While avoiding #16943. - - - - - c3e26ab3 by Ömer Sinan Ağacan at 2019-08-22T22:19:26-04:00 Remove special case in SRT generation with -split-sections Previously we were using an empty ModuleSRTInfo for each Cmm group with -split-section. As far as I can see this has no benefits, and simplifying this makes another patch simpler (!1304). We also remove some outdated comments: we no longer generate one module-level SRT. - - - - - a8300520 by Ömer Sinan Ağacan at 2019-08-23T12:04:15+03:00 Make non-streaming LLVM and C backends streaming This adds a Stream.consume function, uses it in LLVM and C code generators, and removes the use of Stream.collect function which was used to collect streaming Cmm generation results into a list. LLVM and C backends now properly use streamed Cmm generation, instead of collecting Cmm groups into a list before generating LLVM/C code. - - - - - 47070144 by Andreas Klebinger at 2019-08-23T19:26:42-04:00 Use variable length encoding for Binary instances. Use LEB128 encoding for Int/Word variants. This reduces the size of interface files significantly. (~19%). Also includes a few small optimizations to make unboxing work better that I have noticed while looking at the core. - - - - - cff44d86 by Sergei Trofimovich at 2019-08-23T19:27:21-04:00 configure.ac: fix '--disable-dwarf-debug' Before the change ./configure --disable-dwarf-debug enabled DWARF debugging unconditionally. This happened due to use of 5-argument form of `AC_ARG_ENABLE` without actually checking the passed `$enableval` parameter: ``` AC_ARG_ENABLE(dwarf-unwind, [AC_HELP_STRING([--enable-dwarf-unwind], [Enable DWARF unwinding support in the runtime system via elfutils' libdw [default=no]])], [AC_CHECK_LIB(dw, dwfl_attach_state, [UseLibdw=YES], [AC_MSG_ERROR([Cannot find system libdw (required by --enable-dwarf-unwind)])])] [UseLibdw=NO] ) ``` Note: - `[UseLibdw=NO]` is called when `--{enable,disable}-dwarf-unwind` is not passed at all as a parameter (ok). - `[AC_CHECK_LIB(dw, dwfl_attach_state, [UseLibdw=YES],` is called for both: * `--enable-dwarf-unwind` being passed: `$enableval = "yes"` (ok). * --disable-dwarf-unwind` being passed: `$enableval = "no"` (bad). The change is to use 3-argument `AC_ARG_ENABLE` and check for passed value as `"$enable_dwarf_unwind" = "yes"`. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 10763ce0 by Ömer Sinan Ağacan at 2019-08-27T10:45:02+03:00 Some more documentation for typePrimRep1 stuff [skip ci] - - - - - 89487be2 by Ömer Sinan Ağacan at 2019-08-27T15:21:50-04:00 Some tweaks in GHC.Compact haddocks - - - - - ee2fad9e by Andreas Klebinger at 2019-08-27T15:22:28-04:00 Remove redundant OPTIONS_GHC in BlockLayout.hs - - - - - 1c7ec449 by Ömer Sinan Ağacan at 2019-08-28T12:51:12+03:00 Return results of Cmm streams in backends This generalizes code generators (outputAsm, outputLlvm, outputC, and the call site codeOutput) so that they'll return the return values of the passed Cmm streams. This allows accumulating data during Cmm generation and returning it to the call site in HscMain. Previously the Cmm streams were assumed to return (), so the code generators returned () as well. This change is required by !1304 and !1530. Skipping CI as this was tested before and I only updated the commit message. [skip ci] - - - - - a308b435 by Sebastian Graf at 2019-08-28T11:33:49-04:00 Fix #17112 The `mkOneConFull` function of the pattern match checker used to try to guess the type arguments of the data type's type constructor by looking at the ambient type of the match. This doesn't work well for Pattern Synonyms, where the result type isn't even necessarily a TyCon application, and it shows in #11336 and #17112. Also the effort seems futile; why try to try hard when the type checker has already done the hard lifting? After this patch, we instead supply the type constructors arguments as an argument to the function and lean on the type-annotated AST. - - - - - 137c24e1 by Ryan Scott at 2019-08-28T22:36:40-04:00 Balance parentheses in GHC 8.10.1 release notes [ci skip] - - - - - 66282ba5 by luca at 2019-08-28T22:37:19-04:00 Remove Unused flag -ddump-shape [skip ci] - - - - - bf9dfe1c by Ömer Sinan Ağacan at 2019-08-29T04:28:35-04:00 Fix LLVM version check yet again There were two problems with LLVM version checking: - The parser would only parse x and x.y formatted versions. E.g. 1.2.3 would be rejected. - The version check was too strict and would reject x.y formatted versions. E.g. when we support version 7 it'd reject 7.0 ("LLVM version 7.0") and only accept 7 ("LLVM version 7"). We now parse versions with arbitrarily deep minor numbering (x.y.z.t...) and accept versions as long as the major version matches the supported version (e.g. 7.1, 7.1.2, 7.1.2.3 ...). - - - - - fc746e98 by Ben Gamari at 2019-08-29T04:29:13-04:00 gitlab-ci: Fix URL of Darwin's cabal-install tarball This was inadvertently referring to the cabal-install-latest/ directory which is volatile. - - - - - 304067a0 by Ömer Sinan Ağacan at 2019-08-29T09:38:25-04:00 Small optimization in the SRT algorithm Noticed by @simonmar in !1362: If the srtEntry is Nothing, then it should be safe to omit references to this SRT from other SRTs, even if it is a static function. When updating SRT map we don't omit references to static functions (see Note [Invalid optimisation: shortcutting]), but there's no reason to add an SRT entry for a static function if the function is not CAFFY. (Previously we'd add SRT entries for static functions even when they're not CAFFY) Using 9151b99e I checked sizes of all SRTs when building GHC and containers: - GHC: 583736 (HEAD), 581695 (this patch). 2041 less SRT entries. - containers: 2457 (HEAD), 2381 (this patch). 76 less SRT entries. - - - - - 78afc2c9 by Sergei Trofimovich at 2019-08-30T06:14:44-04:00 configure.ac: add --enable-numa switch Before the change ./configure detected numa support automatically withoun a nice way to disable autodetection. The change adds `--enable-numa` / `--disable-numa` switch to override the default. If `--enable-numa` is passed and `libnuma` is not present then configure will fail. Reported-by: Sergey Alirzaev Bug: https://github.com/gentoo-haskell/gentoo-haskell/issues/955 Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - c0956c14 by Vladislav Zavialov at 2019-08-30T06:15:21-04:00 Remove HsUtils/userHsLTyVarBndrs This patch removes 'userHsLTyVarBndrs' and 'userHsTyVarBndrs' from HsUtils. These helper functions were not used anywhere. - - - - - 7e6aeb13 by Eric Wolf at 2019-08-31T10:25:39+02:00 Add additional step to T16804 Add another small test step Use the same identifier name in different scopes and see, if ':uses' handles that. Add another test step to check wether local bindings with the same identifier name might get confused Add easier to understand test output Fix annotated lines from file correctly - - - - - e56251f6 by Ömer Sinan Ağacan at 2019-08-31T17:55:13-04:00 Remove redundant special case in STG pretty-printer This special case existed for no reason, and made things inconsistent. Before Boolean.$bT :: Boolean.Boolean [GblId, Str=m, Unf=OtherCon []] = CAF_ccs \ u [] Boolean.$bT1; After Boolean.$bF :: Boolean.Boolean [GblId, Str=m, Unf=OtherCon []] = \u [] Boolean.$bF1; The cost-centre is now hidden when not profiling, as is the case with other types of closures. - - - - - cfab4abe by Gershom Bazerman at 2019-09-01T00:34:05-04:00 cap max stack size at 32 bit limit (#17019) - - - - - 9acba780 by John Ericson at 2019-09-01T22:44:45-04:00 Use C99 Fixed width types to avoid hack in base's configure Define MD5Context in terms of `uint*_t` and don't use `HsFFI.h`. - - - - - 11679e5b by Ömer Sinan Ağacan at 2019-09-02T13:17:49+03:00 Few tweaks in -ddump-debug output, minor refactoring - Fixes crazy indentation in -ddump-debug output - We no longer dump empty sections in -ddump-debug when a code block does not have any generated debug info - Minor refactoring in Debug.hs and AsmCodeGen.hs - - - - - f96d57b8 by John Ericson at 2019-09-05T18:50:19-04:00 Make the C-- O and C types constructors with DataKinds The tightens up the kinds a bit. I use type synnonyms to avoid adding promotion ticks everywhere. - - - - - b55ee979 by John Ericson at 2019-09-05T18:50:56-04:00 Make sure all boolean settings entries use `YES` / `NO` Some where using `True` / `False`, a legacy of when they were in `Config.hs`. See #16914 / d238d3062a9858 for a similar problem. Also clean up the configure variables names for consistency and clarity while we're at it. "Target" makes clear we are talking about outputted code, not where GHC itself runs. - - - - - 821bece9 by Ömer Sinan Ağacan at 2019-09-07T04:50:21-04:00 Minor refactoring in deriveConstants Mainly we now generate this data PlatformConstants = PlatformConstants { pc_CONTROL_GROUP_CONST_291 :: Int, pc_STD_HDR_SIZE :: Int, pc_PROF_HDR_SIZE :: Int, pc_BLOCK_SIZE :: Int, } instead of data PlatformConstants = PlatformConstants { pc_platformConstants :: () , pc_CONTROL_GROUP_CONST_291 :: Int , pc_STD_HDR_SIZE :: Int , pc_PROF_HDR_SIZE :: Int , pc_BLOCK_SIZE :: Int ... } The first field has no use and according to (removed) comments it was to make code generator's work easier.. if anything this version is simpler because it has less repetition (the commas in strings are gone). - - - - - b0fdd7fe by Alp Mestanogullari at 2019-09-07T04:50:59-04:00 hadrian: fix _build/ghc-stage1 to make it callable from any directory - - - - - 51379b89 by Ömer Sinan Ağacan at 2019-09-08T21:40:32-04:00 Add a new flag -dno-typeable-binds for debugging See the user manual entry -- this helps when debugging as generated Core gets smaller without these bindings. - - - - - d0b45ac6 by Moritz Kiefer at 2019-09-08T21:41:12-04:00 Fix GHC version guard for Int32Rep/Word32Rep Those constructors have been added after GHC 8.8. The version guards in `binary` are correct, see https://github.com/kolmodin/binary/pull/167/files. - - - - - 4cf91d1a by Daniel Gröber at 2019-09-09T05:42:33-04:00 Use lazyness for FastString's z-encoding memoization Having an IORef in FastString to memoize the z-encoded version is unecessary because there is this amazing thing Haskell can do natively, it's called "lazyness" :) We simply remove the UNPACK and strictness annotations from the constructor field corresponding to the z-encoding, making it lazy, and store the (pure) z-encoded string there. The only complication here is 'hasZEncoding' which allows cheking if a z-encoding was computed for a given string. Since this is only used for compiler performance statistics though it's not actually necessary to have the current per-string granularity. Instead I add a global IORef counter to the FastStringTable and use unsafePerformIO to increment the counter whenever a lazy z-encoding is forced. - - - - - f5e2fde4 by Daniel Gröber at 2019-09-09T05:42:33-04:00 Update FastString docstrings 1) FastStrings are always UTF-8 encoded now. 2) Clarify what is meant by "hashed" 3) Add mention of lazy z-enc - - - - - 270fbe85 by Ryan Scott at 2019-09-09T05:43:12-04:00 Replace queryCygwinTerminal with Win32's isMinTTYHandle `SysTools.Terminal.queryCygwinTerminal` now exists in the `Win32` library under the name `isMinTTYHandle` since `Win32-2.5.0.0`. (GHC 8.4.4 ships with `Win32-2.6.1.0`, so this is well within GHC's support window.) We can therefore get replace `queryCygwinTerminal` with `isMinTTYHandle` and delete quite a bit of code from `SysTools.Terminal` in the process. Along the way I needed to replace some uses of `#if defined x` with `#if defined(x)` to please the CI linters. - - - - - 447864a9 by Sylvain Henry at 2019-09-10T00:04:50+02:00 Module hierarchy: StgToCmm (#13009) Add StgToCmm module hierarchy. Platform modules that are used in several other places (NCG, LLVM codegen, Cmm transformations) are put into GHC.Platform. - - - - - 60c26403 by Niklas Hambüchen at 2019-09-11T09:44:23-04:00 linker: Move -optl flags to end of linker invocation. Until now, giving `-optl` linker flags to `ghc` on the command line placed them in the wrong place in the `ld` command line: They were given before all the Haskell libararies, when they should appear after. Background: Most linkers like `ld.bfd` and `ld.gold`, but not the newer LLVM `lld`, work in a way where the order of `-l` flags given matters; earlier `-lmylib1` flags are supposed to create "holes" for linker symbols that are to be filled with later `lmylib2` flags that "fill the holes" for these symbols. As discovered in https://github.com/haskell/cabal/pull/5451#issuecomment-518001240, the `-optl` flags appeared before e.g. the -lHStext-1.2.3.1 -lHSbinary-0.8.6.0 -lHScontainers-0.6.0.1 flags that GHC added at the very end. Haskell libraries typically depend on C libraries, so `-lHS*` flags will create holes for the C libraries to fill in, but that only works when those libraries' `-l` flags are given **after** the `-lHS*` flags; until now they were given before, which was wrong. This meant that Cabal's `--ld-options` flag and `ld-options` `.cabal` file field were pretty ineffective, unless you used the `--ld-option=--start-group` hack as (https://github.com/haskell/cabal/pull/5451#issuecomment-406761676) that convinces the classical linkers to not be dependent on the order of linker flags given. This commit fixes the problem by simply flipping the order, putting `-optl` flags at the end, after Haskell libraries. The code change is effectively only `args1 ++ args` -> `args ++ args1` but the commit also renames the variables for improved clarity. Simple way to test it: ghc --make Main.hs -fforce-recomp -v -optl-s on a `Main.hs` like: import qualified Data.Set as Set main = print $ Set.fromList "hello" - - - - - 7032a913 by John Ericson at 2019-09-11T09:45:02-04:00 Remove COMPILING_GHC It is no longer used. I guess we are sharing fewer headers with the RTS than the comment claims. That's a relief! - - - - - 58569a5b by Peter Trommler at 2019-09-11T09:45:47-04:00 testsuite: check for RTS linker Fixes #16833 - - - - - df6fbe03 by Luke Lau at 2019-09-11T09:46:36-04:00 Bump Hadrian's QuickCheck dependency - - - - - d9e637df by John Ericson at 2019-09-11T09:47:26-04:00 Remove dead `ncgDebugIsOn` and `NCG_DEBUG` Haven't been used since 16206a6603e87e15d61c57456267c5f7ba68050e. - - - - - 7ef6fe8f by Ben Gamari at 2019-09-11T09:48:03-04:00 SetLevels: Fix potential panic in lvlBind 3b31a94d introduced a use of isUnliftedType which can panic in the case of levity-polymorphic types. Fix this by introducing mightBeUnliftedType which returns whether the type is *guaranteed* to be lifted. - - - - - c76cc0c6 by Ömer Sinan Ağacan at 2019-09-11T19:40:06-04:00 Refactor bad coercion checking in a few places We do bad coercion checking in a few places in the compiler, but they all checked it differently: - CoreToStg.coreToStgArgs: Disallowed lifted-to-unlifted, disallowed changing prim reps even when the sizes are the same. - StgCmmExpr.cgCase: Checked primRepSlot equality. This disallowed Int to Int64 coercions on 64-bit systems (and Int to Int32 on 32-bit) even though those are fine. - CoreLint: Only place where we do this right. Full rules are explained in Note [Bad unsafe coercion]. This patch implements the check explained in Note [Bad unsafe coercion] in CoreLint and uses it in CoreToStg.coreToStgArgs and StgCmmExpr.cgCase. This fixes #16952 and unblocks !1381 (which fixes #16893). This is the most conservative and correct change I came up with that fixes #16952. One remaining problem with coercion checking is that it's currently done in seemingly random places. What's special about CoreToStg.coreToStgArgs and StgCmmExpr.cgCase? My guess is that adding assertions to those places caught bugs before so we left assertions in those places. I think we should remove these assertions and do coercion checking in CoreLint and StgLint only (#17041). - - - - - 3a7d3923 by Tamar Christina at 2019-09-11T19:40:53-04:00 Windows: make openTempFile fully atomic. - - - - - 98b0d6ee by Pranay Sashank at 2019-09-12T04:52:33-04:00 Print the correct system memory in use with +RTS -s (#17158) Use `stats.max_mem_in_use_bytes` to print the memory usage instead of `stats.max_live_bytes` which prints maximum residency. Fixes (#17158). - - - - - a06629b4 by John Ericson at 2019-09-12T04:53:13-04:00 Do not throw away backpack instantiations for module lookup cache Currently, there is only one home package so this probably doesn't matter. But if we support multiple home packages, they could differ only in arguments (same indef component being applied). It looks like it used to be this way before 4e8a0607140b23561248a41aeaf837224aa6315b, but that commit doesn't seem to comment on this change in the particular. (It's main purpose is creating the InstalledUnitId and recategorizing the UnitId expressions accordingly.) Trying this as a separate commit for testing purposes. I leave it to others to decide whether this is a good change on its own. - - - - - 09fa5654 by John Ericson at 2019-09-12T04:53:51-04:00 Remove unused `#include`s from parser/cutils.c Looks like these have been unused since 7c665f9ce0980ee7c81a44c8f861686395637453. - - - - - 2b37a79d by Sebastian Graf at 2019-09-12T14:05:29-04:00 Bump Cabal submodule to 3.1 ------------------------- Metric Increase: haddock.Cabal T4029 ------------------------- - - - - - 86753475 by Ningning Xie at 2019-09-12T14:06:07-04:00 Fix StandaloneDeriving If I understand correctly, `deriving instance _ => Eq (Foo a)` is equivalent to `data Foo a deriving Eq`, rather than `data Foo a deriving Foo`. - - - - - a733002a by Ben Gamari at 2019-09-13T03:09:47-04:00 Update mailmap - - - - - 5b64aee2 by Simon Peyton Jones at 2019-09-13T03:10:26-04:00 Fix scoping of implicit parameters There was an outright bug in TcInteract.solveOneFromTheOther which meant that we did not always pick the innermost implicit parameter binding, causing #17104. The fix is easy, just a rearrangement of conditional tests - - - - - 47b12660 by Tamar Christina at 2019-09-13T03:11:06-04:00 Windows: Fix hsc2hs non-deterministic failures. - - - - - e3a7592b by Alp Mestanogullari at 2019-09-13T03:11:50-04:00 Add a test to make sure we don't regress on #17140 in the future - - - - - 6f3cd50e by Zubin Duggal at 2019-09-13T11:24:51-04:00 Explain how to update HieAst [skip ci] - - - - - 71428a43 by Zubin Duggal at 2019-09-13T11:24:51-04:00 Address review comments [skip CI] - - - - - ccb4e646 by John Ericson at 2019-09-13T11:25:29-04:00 Compiler should always get fingerprinting impl from base 07ee15915d5a0d6d1aeee137541eec6e9c153e65 started the transition, but the job was never finished. - - - - - c45c89d6 by Ben Gamari at 2019-09-13T11:26:05-04:00 gitlab: Add issue template for documentation issues Fixes #17180. - - - - - a0e220b7 by John Ericson at 2019-09-13T11:26:43-04:00 Remove empty NCG.h - - - - - 046ca133 by Andrew Martin at 2019-09-13T15:43:16-04:00 Add predicates for testing if IOError is ResourceVanished. This adds isResourceVanished, resourceVanishedErrorType, and isResourceVanishedErrorType to System.IO.Error, resolving #14730. - - - - - bd079345 by taylorfausak at 2019-09-14T06:25:27-04:00 Fix CONLIKE typo - - - - - cf7e78a3 by Ben Gamari at 2019-09-15T23:46:36-04:00 Rename GHC.StgToCmm.Con -> GHC.StgToCmm.DataCon Incredibly, Windows disallows the manipulation of any file matching Con(\..*)?. The `GHC.StgToCmm.Con` was introduced in the renamings in 447864a9, breaking the Windows build. Work around this by renaming it to `GHC.StgToCmm.DataCon` Fixes #17187. - - - - - 7208160d by Sylvain Henry at 2019-09-15T23:47:22-04:00 Fix Hadrian build with Stack (#17189) Broken by 2b37a79d61e9b3787873dc9f7458ef2bde4809b0 - - - - - b5ae3868 by Sylvain Henry at 2019-09-16T13:32:22-04:00 Allow validation with Hadrian built with Stack [skip ci] - - - - - 7915afc6 by Sebastian Graf at 2019-09-16T13:33:05-04:00 Encode shape information in `PmOracle` Previously, we had an elaborate mechanism for selecting the warnings to generate in the presence of different `COMPLETE` matching groups that, albeit finely-tuned, produced wrong results from an end user's perspective in some cases (#13363). The underlying issue is that at the point where the `ConVar` case has to commit to a particular `COMPLETE` group, there's not enough information to do so and the status quo was to just enumerate all possible complete sets nondeterministically. The `getResult` function would then pick the outcome according to metrics defined in accordance to the user's guide. But crucially, it lacked knowledge about the order in which affected clauses appear, leading to the surprising behavior in #13363. In !1010 we taught the term oracle to reason about literal values a variable can certainly not take on. This MR extends that idea to `ConLike`s and thereby fixes #13363: Instead of committing to a particular `COMPLETE` group in the `ConVar` case, we now split off the matching constructor incrementally and record the newly covered case as a refutable shape in the oracle. Whenever the set of refutable shapes covers any `COMPLETE` set, the oracle recognises vacuosity of the uncovered set. This patch goes a step further: Since at this point the information in value abstractions is merely a cut down representation of what the oracle knows, value abstractions degenerate to a single `Id`, the semantics of which is determined by the oracle state `Delta`. Value vectors become lists of `[Id]` given meaning to by a single `Delta`, value set abstractions (of which the uncovered set is an instance) correspond to a union of `Delta`s which instantiate the same `[Id]` (akin to models of formula). Fixes #11528 #13021, #13363, #13965, #14059, #14253, #14851, #15753, #17096, #17149 ------------------------- Metric Decrease: ManyAlternatives T11195 ------------------------- - - - - - ae4415b9 by Matthew Pickering at 2019-09-17T19:21:10-04:00 eventlog: Add biographical and retainer profiling traces This patch adds a new eventlog event which indicates the start of a biographical profiler sample. These are different to normal events as they also include the timestamp of when the census took place. This is because the LDV profiler only emits samples at the end of the run. Now all the different profiling modes emit consumable events to the eventlog. - - - - - 9c21b2fd by Richard Eisenberg at 2019-09-17T19:22:00-04:00 Fix #13571 by adding an extension flag check Test case: indexed-types/should_fail/T13571 - - - - - 8039b125 by Simon Peyton Jones at 2019-09-17T19:22:50-04:00 Comments only - - - - - 1c3af277 by Simon Peyton Jones at 2019-09-17T19:23:37-04:00 Improve error message for out-of-scope variables + VTA As #13834 and #17150 report, we get a TERRIBLE error message when you have an out of scope variable applied in a visible type application: (outOfScope @Int True) This very simple patch improves matters. See TcExpr Note [VTA for out-of-scope functions] - - - - - c77fc3b2 by John Ericson at 2019-09-17T19:24:20-04:00 Deduplicate `HaskellMachRegs.h` and `RtsMachRegs.h` headers Until 0472f0f6a92395d478e9644c0dbd12948518099f there was a meaningful host vs target distinction (though it wasn't used right, in genapply). After that, they did not differ in meaningful ways, so it's best to just only keep one. - - - - - c3eaaca6 by Simon Peyton Jones at 2019-09-19T09:03:19-04:00 Add a missing update of sc_hole_ty (#16312) In simplCast I totally failed to keep the sc_hole_ty field of ApplyToTy (see Note [The hole type in ApplyToTy]) up to date. When a cast goes by, of course the hole type changes. Amazingly this has not bitten us before, but #16312 finally triggered it. Fortunately the fix is simple. Fixes #16312. - - - - - de1723b2 by Ben Gamari at 2019-09-19T09:03:19-04:00 Simplify: Lazy pattern match - - - - - d9c6b86e by Richard Eisenberg at 2019-09-19T09:04:03-04:00 Refactor kindGeneralize and friends This commit should have no change in behavior.(*) The observation was that Note [Recipe for checking a signature] says that every metavariable in a type-checked type must either (A) be generalized (B) be promoted (C) be zapped. Yet the code paths for doing these were all somewhat separate. This led to some steps being skipped. This commit shores this all up. The key innovation is TcHsType.kindGeneralizeSome, with appropriate commentary. This commit also sets the stage for #15809, by turning the WARNing about bad level-numbers in generalisation into an ASSERTion. The actual fix for #15809 will be in a separate commit. Other changes: * zonkPromoteType is now replaced by kindGeneralizeNone. This might have a small performance degradation, because zonkPromoteType zonked and promoted all at once. The new code path promotes first, and then zonks. * A call to kindGeneralizeNone was added in tcHsPartialSigType. I think this was a lurking bug, because it did not follow Note [Recipe for checking a signature]. I did not try to come up with an example showing the bug. This is the (*) above. Because of this change, there is an error message regression in partial-sigs/should_fail/T14040a. This problem isn't really a direct result of this refactoring, but is a symptom of something deeper. See #16775, which addresses the deeper problem. * I added a short-cut to quantifyTyVars, in case there's nothing to quantify. * There was a horribly-outdated Note that wasn't referred to. Gone now. * While poking around with T14040a, I discovered a small mistake in the Coercion.simplifyArgsWorker. Easy to fix, happily. * See new Note [Free vars in coercion hole] in TcMType. Previously, we were doing the wrong thing when looking at a coercion hole in the gather-candidates algorithm. Fixed now, with lengthy explanation. Metric Decrease: T14683 - - - - - f594a68a by Richard Eisenberg at 2019-09-19T09:04:03-04:00 Use level numbers for generalisation This fixes #15809, and is covered in Note [Use level numbers for quantification] in TcMType. This patch removes the "global tyvars" from the environment, a nice little win. - - - - - c675d08f by Richard Eisenberg at 2019-09-19T09:04:03-04:00 Test #17077. - - - - - 912afaf4 by Ben Gamari at 2019-09-19T09:04:39-04:00 CoreUtils: Use mightBeUnliftedType in exprIsTopLevelBindable Also add reference from isUnliftedType to mightBeUnliftedType. - - - - - baf47661 by Sebastian Graf at 2019-09-19T09:05:20-04:00 Extract PmTypes module from PmExpr and PmOracle Apparently ghc-lib-parser's API blew up because the newly induced cyclic dependency between TcRnTypes and PmOracle pulled in the other half of GHC into the relevant strongly-connected component. This patch arranges it so that PmTypes exposes mostly data type definitions and type class instances to be used within PmOracle, without importing the any of the possibly offending modules DsMonad, TcSimplify and FamInst. - - - - - 2a8867cf by Sebastian Graf at 2019-09-19T09:05:58-04:00 Add a regression test for #11822 The particular test is already fixed, but the issue seems to have multiple different test cases lumped together. - - - - - 52173990 by Ben Gamari at 2019-09-19T09:06:36-04:00 testsuite: Add testcase for #17206 - - - - - b3e5c731 by Alp Mestanogullari at 2019-09-19T21:42:17-04:00 ErrUtils: split withTiming into withTiming and withTimingSilent 'withTiming' becomes a function that, when passed '-vN' (N >= 2) or '-ddump-timings', will print timing (and possibly allocations) related information. When additionally built with '-eventlog' and executed with '+RTS -l', 'withTiming' will also emit both 'traceMarker' and 'traceEvent' events to the eventlog. 'withTimingSilent' on the other hand will never print any timing information, under any circumstance, and will only emit 'traceEvent' events to the eventlog. As pointed out in !1672, 'traceMarker' is better suited for things that we might want to visualize in tools like eventlog2html, while 'traceEvent' is better suited for internal events that occur a lot more often and that we don't necessarily want to visualize. This addresses #17138 by using 'withTimingSilent' for all the codegen bits that are expressed as a bunch of small computations over streams of codegen ASTs. - - - - - 4853d962 by Ben Gamari at 2019-09-19T21:42:55-04:00 users guide: Fix link to let generalization blog post Fixes #17200. - - - - - 51192964 by Sylvain Henry at 2019-09-20T05:14:34-04:00 Module hierarchy: Hs (#13009) Add GHC.Hs module hierarchy replacing hsSyn. Metric Increase: haddock.compiler - - - - - 2f8ce45a by Ben Gamari at 2019-09-20T05:15:11-04:00 testsuite: Add test for #17202 - - - - - f257bf73 by Matthew Pickering at 2019-09-20T05:15:52-04:00 hadrian/ghci.sh: Enable building in parallel - - - - - 070f7b85 by Matthew Pickering at 2019-09-20T05:15:52-04:00 Remove trailing whitespace - - - - - 5390b553 by Matthew Pickering at 2019-09-20T05:15:52-04:00 Pass -j to ghc-in-ghci CI job - - - - - 1b7e1d31 by John Ericson at 2019-09-20T05:16:36-04:00 Remove pointless partiality in `Parser.ajs` - - - - - 17554248 by Simon Peyton Jones at 2019-09-20T10:50:21+01:00 Fix PmOracle.addVarCoreCt in-scope set PmOracle.addVarCoreCt was giving a bogus (empty) in-scope set to exprIsConApp_maybe, which resulted in a substitution-invariant failure (see MR !1647 discussion). This patch fixes it, by taking the free vars of the expression. - - - - - 0dad81ca by Simon Peyton Jones at 2019-09-20T10:50:21+01:00 Fix bogus type of case expression Issue #17056 revealed that we were sometimes building a case expression whose type field (in the Case constructor) was bogus. Consider a phantom type synonym type S a = Int and we want to form the case expression case x of K (a::*) -> (e :: S a) We must not make the type field of the Case constructor be (S a) because 'a' isn't in scope. We must instead expand the synonym. Changes in this patch: * Expand synonyms in the new function CoreUtils.mkSingleAltCase. * Use mkSingleAltCase in MkCore.wrapFloat, which was the proximate source of the bug (when called by exprIsConApp_maybe) * Use mkSingleAltCase elsewhere * Documentation CoreSyn new invariant (6) in Note [Case expression invariants] CoreSyn Note [Why does Case have a 'Type' field?] CoreUtils Note [Care with the type of a case expression] * I improved Core Lint's error reporting, which was pretty confusing in this case, because it didn't mention that the offending type was the return type of a case expression. * A little bit of cosmetic refactoring in CoreUtils - - - - - 1ea8c451 by Sebastian Graf at 2019-09-21T09:52:34-04:00 PredType for type constraints in the pattern match checker instead of EvVar Using EvVars for capturing type constraints implied side-effects in DsM when we just wanted to *construct* type constraints. But giving names to type constraints is only necessary when passing Givens to the type checker, of which the majority of the pattern match checker should be unaware. Thus, we simply generate `newtype TyCt = TyCt PredType`, which are nicely stateless. But at the same time this means we have to allocate EvVars when we want to query the type oracle! So we keep the type oracle state as `newtype TyState = TySt (Bag EvVar)`, which nicely makes a distinction between new, unchecked `TyCt`s and the inert set in `TyState`. - - - - - ded96fb3 by Ömer Sinan Ağacan at 2019-09-21T09:53:29-04:00 Document MIN_PAYLOAD_SIZE and mark-compact GC mark bits This updates the documentation of the MIN_PAYLOAD_SIZE constant and adds a new Note [Mark bits in mark-compact collector] explaning why the mark-compact collector uses two bits per objet and why we need MIN_PAYLOAD_SIZE. - - - - - a7867c79 by Sebastian Graf at 2019-09-21T14:56:58+01:00 Get rid of PmFake The pattern match oracle can now cope with the abundance of information that ViewPatterns, NPlusKPats, overloaded lists, etc. provide. No need to have PmFake anymore! Also got rid of a spurious call to `allCompleteMatches`, which we used to call *for every constructor* match. Naturally this blows up quadratically for programs like `ManyAlternatives`. ------------------------- Metric Decrease: ManyAlternatives Metric Increase: T11822 ------------------------- - - - - - fa66e3e5 by Alp Mestanogullari at 2019-09-21T23:31:08-04:00 Fix haddocks for marker events in Debug.Trace - - - - - da12da79 by Daniel Gröber at 2019-09-22T14:34:56+02:00 rts: retainer: Remove cStackSize debug counter This can only ever be one since 5f1d949ab9 ("Remove explicit recursion in retainer profiling"), so it's pointless. - - - - - 3ebaa4b5 by Daniel Gröber at 2019-09-22T15:17:53+02:00 rts: Remove bitrotten retainer debug code The `defined(DEBUG_RETAINER) == true` branch doesn't even compile anymore because 1) retainerSet was renamed to RetainerSet and 2) even if I fix that the context in Rts.h seems to have changed such that it's not in scope. If 3) I fix that 'flip' is still not in scope :) At that point I just gave up. - - - - - 63023dc2 by Daniel Gröber at 2019-09-22T15:18:09+02:00 rts: Fix outdated references to 'ldvTime' This got renamed to 'era' in dbef766ce7 ("[project @ 2001-11-26 16:54:21 by simonmar] Profiling cleanup"). - - - - - ead05f80 by Daniel Gröber at 2019-09-22T15:18:09+02:00 rts: retainer: Turn global traversal state into a struct Global state is ugly and hard to test. Since the profiling code isn't quite as performance critical as, say, GC we should prefer better code here. I would like to move the 'flip' bit into the struct too but that's complicated by the fact that the defines which use it directly are also called from ProfHeap where the traversalState is not easily available. Maybe in a future commit. - - - - - 94ecdb4f by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move info.next.parent to stackElement I don't see a point in having this live in 'info', just seems to make the code more complicated. - - - - - f79ac2ef by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Generalise per-stackElement data This essentially ammounts to s/retainer/stackData/, s/c_child_r/data/ and some temporary casting of c_child_r to stackData until refactoring of this module is completed by a subsequent commit. We also introduce a new union 'stackData' which will contain the actual extra data to be stored on the stack. The idea is to make the heap traversal logic of the retainer profiler ready for extraction into it's own module. So talking about "retainers" there doesn't really make sense anymore. Essentially the "retainers" we store in the stack are just data associated with the push()ed closures which we return when pop()ing it. - - - - - f083358b by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Fix comment typo s/keeps/keep/ - - - - - 2f2f6dd5 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: Generalise profiling heap traversal flip bit handling This commit starts renaming some flip bit related functions for the generalised heap traversal code and adds provitions for sharing the per-closure profiling header field currently used exclusively for retainer profiling with other heap traversal profiling modes. - - - - - e40b3c23 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: GC: Remove redundant #include "RetainerProfiler.h" - - - - - b03db9da by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Pull retainer specific code into a callback This essentially turns the heap traversal code into a visitor. You add a bunch of roots to the work-stack and then the callback you give to traverseWorkStack() will be called with every reachable closure at least once. - - - - - 48e816f0 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: simplify pop() control flow Instead of breaking out of the switch-in-while construct using `return` this uses `goto out` which makes it possible to share a lot of the out-variable assignment code in all the cases. I also replaced the nasty `while(true)` business by the real loop condition: `while(*c == NULL)`. All `break` calls inside the switch aready have either a check for NULL or an assignment of `c` to NULL so this should not change any behaviour. Using `goto out` also allowed me to remove another minor wart: In the MVAR_*/WEAK cases the popOff() call used to happen before reading the stackElement. This looked like a use-after-free hazard to me as the stack is allocated in blocks and depletion of a block could mean it getting freed and possibly overwritten by zero or garbage, depending on the block allocator's behaviour. - - - - - b92ed68a by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: Add note reference to SET_PROF_HDR for profiling 'flip' bit - - - - - f3bb7397 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerSet: Remove obsolete fist/second-approach choice In the old code when DEBUG_RETAINER was set, FIRST_APPROACH is implied. However ProfHeap.c now depends on printRetainerSetShort which is only available with SECOND_APPROACH. This is because with FIRST_APPROACH retainerProfile() will free all retainer sets before returning so by the time ProfHeap calls dumpCensus the retainer set pointers are segfaulty. Since all of this debugging code obviously hasn't been compiled in ages anyways I'm taking the liberty of just removing it. Remember guys: Dead code is a liability not an asset :) - - - - - ec1d76e2 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Remove obsolete debug code Commit dbef766ce7 ("Profiling cleanup.") made this debug code obsolete by removing the 'cost' function without a replacement. As best I can tell the retainer profiler used to do some heap census too and this debug code was mainly concerned with that. - - - - - b7e15d17 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Rename heap traversal functions for extraction This gets all remaining functions in-line with the new 'traverse' prefix and module name. - - - - - 64ec45a7 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Reduce DEBUG_RETAINER ifdef noise Keeping track of the maximum stack seems like a good idea in all configurations. The associated ASSERTs only materialize in debug mode but having the statistic is nice. To make the debug code less prone to bitrotting I introduce a function 'debug()' which doesn't actually print by default and is #define'd away only when the standard DEBUG define is off. - - - - - bd78b696 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Cleanup comments and strings for traversal extraction A lot of comments and strings are still talking about old names, fix that. - - - - - cb7220b3 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Remove outdated invariants on traversePushStack These invariants don't seem to make any sense in the current code. The text talks about c_child_r as if it were an StgClosure, for which RSET() would make sense, but it's a retainer aka 'CostCentreStack*'. - - - - - bb92660c by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Use global STATIC_INLINE macro STATIC_INLINE already does what the code wanted here, no need to duplicate the functionality here. - - - - - 2b76cf9e by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move heap traversal declarations to new header - - - - - 44d5cc0d by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Abstract maxStackSize for generic traversal - - - - - fd213d17 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Update obsolete docs for traverseMaybeInitClosureData - - - - - 39f2878c by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move actual 'flip' bit flip to generic traversal code - - - - - f9b4c4f2 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Remove traverse-stack chunk support There's simply no need anymore for this whole business. Instead of individually traversing roots in retainRoot() we just push them all onto the stack and traverse everything in one go. This feature was not really used anyways. There is an `ASSERT(isEmptyWorkStack(ts))` at the top of retainRoot() which means there really can't ever have been any chunks at the toplevel. The only place where this was probably used is in traversePushStack but only way back when we were still using explicit recursion on the C callstack. Since the code was changed to use an explicit traversal-stack these stack-chunks can never escape one call to traversePushStack anymore. See commit 5f1d949ab9 ("Remove explicit recursion in retainer profiling") - - - - - c7def600 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move mut_list reset to generic traversal code - - - - - 9bf27060 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Make visit callback easier to implement Currently it is necessary for user code to expend at least one extra bit in the closure header just to know whether visit() should return true or false, to indicate if children should be traversed. The generic traversal code already has this information in the visited bit so simply pass it to the visit callback. - - - - - 96adf179 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Improve Note [Profiling heap traversal visited bit] - - - - - 187192a6 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerProfile.c: Re-enable and fix warnings Turns out some genius disabled warnings for RetainerProfile.c in the build system. That would have been good to know about five silent type mismatch crashes ago.. :) - - - - - eb29735e by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerProfile.c: Minimize #includes A lot of these includes are presumably leftovers from when the retainer profiler still did it's own heap profiling. - - - - - 383f9089 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: Split heap traversal from retainer profiler This finally moves the newly generalised heap traversal code from the retainer profiler into it's own file. - - - - - 52c5ea71 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: TraverseHeap: Make comment style consistent - - - - - 75355228 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: TraverseHeap: Make pushStackElement argument const - - - - - a8137780 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: TraverseHeap: Move stackElement.cp back into nextPos union The 'cp' field really is only used when type==posTypeFresh so it's more space efficient to have it in the nextPos union. - - - - - 7f10cc2d by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerProfile: Explain retainVisitClosure return values [ci skip] - - - - - 111f2761 by Daniel Gröber at 2019-09-22T15:33:41+02:00 rts: TraverseHeap: Add doc comment for getTraverseStackMaxSize - - - - - 68ddb43c by Ben Gamari at 2019-09-23T00:34:00-04:00 gitlab-ci: Fix URL of Windows cabal-install tarball - - - - - 0e478407 by Takenobu Tani at 2019-09-23T17:51:37-04:00 users-guide: Fix links and formats for GHC 8.10 This commit only fixes links and markdown syntax. [skip ci] - - - - - 74631bbc by Adam Sandberg Eriksson at 2019-09-23T17:52:32-04:00 base: add newtypes for socklen_t and ndfs_t to System.Posix.Types #16568 Metric Increase: haddock.base T4029 - - - - - 4470a144 by Björn Gohla at 2019-09-23T17:53:23-04:00 add Hadrian rule to build user guide as Info book - - - - - dbbea5a8 by Björn Gohla at 2019-09-23T17:53:23-04:00 use the Make builder instead of raw cmd_ - - - - - b0e3b173 by Björn Gohla at 2019-09-23T17:53:23-04:00 detect makeinfo in configure(.ac) - - - - - 9fe4d2df by Björn Gohla at 2019-09-23T17:53:23-04:00 explicit dependence on makeinfo - - - - - b650c2b6 by Björn Gohla at 2019-09-23T17:53:23-04:00 alphabetical ordering - - - - - 27789294 by Björn Gohla at 2019-09-23T17:53:23-04:00 sort-paragraphs in runBuilderWith - - - - - d0c2f3a2 by Artem Pyanykh at 2019-09-23T17:54:04-04:00 [hadrian] Rebuild programs on dynamicGhcPrograms/ghcProfiled change Currently, if you change these ^ flavour parameters, rebuilding is not triggered, since `programContext` doesn't set up a dependency on those values. Exposing these values via an oracle does set the dependency and properly triggers a rebuild of binaries. Several attempts to factor out these actions ended up in cyclic dependency here or there. I'm not absolutely happy with this variant either, but at least it works. ==== Issue repro: In UserSettings.hs: ``` dbgDynamic = defaultFlavour { name = "dbg-dynamic" , dynamicGhcPrograms = pure True, ... } dbgStatic = defaultFlavour { name = "dbg-static" , dynamicGhcPrograms = pure False ... } ``` Then in console: ``` $ hadrian/build.sh -j --flavour=dbg-dynamic ... does the build $ hadrian/build.sh -j --flavour=dbg-static ... does nothing, considers binaries up to date ``` - - - - - 238b58e4 by Kari Pahula at 2019-09-23T17:54:42-04:00 Add -fkeep-going to make compiler continue despite errors (#15424) Add a new optional failure handling for upsweep which continues the compilation on other modules if any of them has errors. - - - - - 146f26cc by Sebastian Graf at 2019-09-24T01:06:40-04:00 Some leftovers from !1732. Comments only [skip ci] - - - - - b5f24fb4 by Takenobu Tani at 2019-09-24T01:07:19-04:00 Hadrian: Add -haddock option for GHCi's :doc command This commit adds -haddock option to Hadrian-based build system. To enable :doc command on GHCi, core libraries must be compiled with -haddock option. Especially, the `-haddock` option is essential for a release build. Assuming current GitLab CI condition (.gitlab-ci.yml), I add -haddock option to the default flavour only. This has already been done for Make-based build system. Please see #16415. - - - - - f97a7aac by Sebastian Graf at 2019-09-24T01:07:57-04:00 Fix some duplication in the parser D3673 experienced reduce/reduce conflicts when trying to use opt_instance for associated data families. That was probably because the author tried to use it for Haskell98-syntax without also applying it to GADT-syntax, which actually leads to a reduce/reduce conflict. Consider the following state: ``` data . T = T data . T where T :: T ``` The parser must decide at this point whether or not to reduce an empty `opt_instance`. But doing so would also commit to either Haskell98 or GADT syntax! Good thing we also accept an optional "instance" for GADT syntax, so the `opt_instance` is there in both productions and there's no reduce/reduce conflict anymore. Also no need to inline `opt_instance`, how it used to be. - - - - - b23f01fd by Ben Gamari at 2019-09-24T08:49:43-04:00 base: Add link to "A reflection on types" Fixes #17181. - - - - - 4bbe0dba by Ben Gamari at 2019-09-24T08:50:20-04:00 gitlab-ci: Bump ci-images This bumps the CI Docker images to ghc/ci-images at 990c5217d1d0e03aea415f951afbc3b1a89240c6. - - - - - 6bca867c by Ben Gamari at 2019-09-24T08:50:59-04:00 hadrian: Update source-repository - - - - - b2d47536 by Ben Gamari at 2019-09-24T08:51:45-04:00 testsuite: Mark threadstatus-9333 as fragile in profthreaded Due to #16555. - - - - - ed520678 by Andreas Klebinger at 2019-09-24T21:08:42-04:00 Fix bounds check in ocResolve_PEi386 for relocation values. The old test was wrong at least for gcc and the value -2287728808L. It also relied on implementation defined behaviour (right shift on a negative value), which might or might not be ok. Either way it's now a simple comparison which will always work. - - - - - 218c5dbf by Matthew Pickering at 2019-09-24T21:09:23-04:00 Add ghcide configuration files This commit adds three new files 1. A hie.yaml file to the project root which specifies to IDEs how to set up the correct environment for loading GHC. This currently specifies to call the `./hadrian/hie-bios` script. 2. A `hie.yaml` file for the hadrian subcomponent, which uses the `cabal` cradle type. 2. The `./hadrian/hie-bios` script which supplies the correct arguments for an IDE to start a session. With these two files it is possible to run ``` ghcide compiler/ ``` and successfully load all the modules for use in the IDE. or ``` ghcide --cwd hadrian/ src/ ``` to test loading all of Hadrian's modules. Closes #17194 - - - - - 2970dc7a by Kari Pahula at 2019-09-25T13:52:48-04:00 Add -Wderiving-defaults (#15839) Enabling both DeriveAnyClass and GeneralizedNewtypeDeriving can cause a warning when no explicit deriving strategy is in use. This change adds an enable/suppress flag for it. - - - - - 4540bbe2 by John Ericson at 2019-09-25T13:53:42-04:00 includes/CodeGen.Platform.hs don't include ghcautoconf.h It doesn't need it, and it shouldn't need it or else multi-target will break. - - - - - ebc65025 by Sebastian Graf at 2019-09-25T13:54:22-04:00 PmCheck: Only ever check constantly many models against a single pattern Introduces a new flag `-fmax-pmcheck-deltas` to achieve that. Deprecates the old `-fmax-pmcheck-iter` mechanism in favor of this new flag. >From the user's guide: Pattern match checking can be exponential in some cases. This limit makes sure we scale polynomially in the number of patterns, by forgetting refined information gained from a partially successful match. For example, when matching `x` against `Just 4`, we split each incoming matching model into two sub-models: One where `x` is not `Nothing` and one where `x` is `Just y` but `y` is not `4`. When the number of incoming models exceeds the limit, we continue checking the next clause with the original, unrefined model. This also retires the incredibly hard to understand "maximum number of refinements" mechanism, because the current mechanism is more general and should catch the same exponential cases like PrelRules at the same time. ------------------------- Metric Decrease: T11822 ------------------------- - - - - - d90d0bad by Ben Gamari at 2019-09-25T13:55:09-04:00 base: Move Ix typeclass to GHC.Ix The `Ix` class seems rather orthogonal to its original home in `GHC.Arr`. - - - - - 795986aa by Ryan Scott at 2019-09-25T13:56:07-04:00 Remove unneeded CPP now that GHC 8.6 is the minimum The minimum required GHC version for bootstrapping is 8.6, so we can get rid of some unneeded `#if `__GLASGOW_HASKELL__` CPP guards, as well as one `MIN_VERSION_ghc_prim(0,5,3)` guard (since GHC 8.6 bundles `ghc-prim-0.5.3`). - - - - - 0b5eede9 by Vladislav Zavialov at 2019-09-25T21:06:04+03:00 Standalone kind signatures (#16794) Implements GHC Proposal #54: .../ghc-proposals/blob/master/proposals/0054-kind-signatures.rst With this patch, a type constructor can now be given an explicit standalone kind signature: {-# LANGUAGE StandaloneKindSignatures #-} type Functor :: (Type -> Type) -> Constraint class Functor f where fmap :: (a -> b) -> f a -> f b This is a replacement for CUSKs (complete user-specified kind signatures), which are now scheduled for deprecation. User-facing changes ------------------- * A new extension flag has been added, -XStandaloneKindSignatures, which implies -XNoCUSKs. * There is a new syntactic construct, a standalone kind signature: type <name> :: <kind> Declarations of data types, classes, data families, type families, and type synonyms may be accompanied by a standalone kind signature. * A standalone kind signature enables polymorphic recursion in types, just like a function type signature enables polymorphic recursion in terms. This obviates the need for CUSKs. * TemplateHaskell AST has been extended with 'KiSigD' to represent standalone kind signatures. * GHCi :info command now prints the kind signature of type constructors: ghci> :info Functor type Functor :: (Type -> Type) -> Constraint ... Limitations ----------- * 'forall'-bound type variables of a standalone kind signature do not scope over the declaration body, even if the -XScopedTypeVariables is enabled. See #16635 and #16734. * Wildcards are not allowed in standalone kind signatures, as partial signatures do not allow for polymorphic recursion. * Associated types may not be given an explicit standalone kind signature. Instead, they are assumed to have a CUSK if the parent class has a standalone kind signature and regardless of the -XCUSKs flag. * Standalone kind signatures do not support multiple names at the moment: type T1, T2 :: Type -> Type -- rejected type T1 = Maybe type T2 = Either String See #16754. * Creative use of equality constraints in standalone kind signatures may lead to GHC panics: type C :: forall (a :: Type) -> a ~ Int => Constraint class C a where f :: C a => a -> Int See #16758. Implementation notes -------------------- * The heart of this patch is the 'kcDeclHeader' function, which is used to kind-check a declaration header against its standalone kind signature. It does so in two rounds: 1. check user-written binders 2. instantiate invisible binders a la 'checkExpectedKind' * 'kcTyClGroup' now partitions declarations into declarations with a standalone kind signature or a CUSK (kinded_decls) and declarations without either (kindless_decls): * 'kinded_decls' are kind-checked with 'checkInitialKinds' * 'kindless_decls' are kind-checked with 'getInitialKinds' * DerivInfo has been extended with a new field: di_scoped_tvs :: ![(Name,TyVar)] These variables must be added to the context in case the deriving clause references tcTyConScopedTyVars. See #16731. - - - - - 4f81fab0 by Ryan Scott at 2019-09-26T14:04:38-04:00 Make -fbyte-code prevent unboxed tuples/sums from implying object code (#16876) This resolves #16876 by making the explicit use of `-fbyte-code` prevent code that enables `UnboxedTuples` or `UnboxedSums` from automatically compiling to object code. This allows for a nice middle ground where most code that enables `UnboxedTuples`/-`Sums` will still benefit from automatically enabling `-fobject-code`, but allows power users who wish to avoid this behavior in certain corner cases (such as `lens`, whose use case is documented in #16876) to do so. Along the way, I did a little cleanup of the relevant code and documentation: * `enableCodeGenForUnboxedTuples` was only checking for the presence of `UnboxedTuples`, but `UnboxedSums` has the same complications. I fixed this and renamed the function to `enableCodeGenForUnboxedTuplesOrSums`. * I amended the users' guide with a discussion of these issues. - - - - - 289fc8da by Sebastian Graf at 2019-09-27T22:10:17-04:00 PmCheck: Elaborate what 'model' means in the user guide [skip ci] - - - - - 9c02a793 by Ron Mordechai at 2019-09-27T22:11:06-04:00 Allow users to disable Unicode with an env var Unicode renders funny on my terminal and I like to avoid it where possible. Most applications which print out non-ascii characters allow users to disable such prints with an environment variable (e.g. Homebrew). This diff disables Unicode usage when the environment variable `GHC_NO_UNICODE` is set. To test, set the env var and compile a bad program. Note that GHC does not print Unicode bullets but instead prints out asterisks: ``` $ GHC_NO_UNICODE= _build/stage1/bin/ghc ../Temp.hs [1 of 1] Compiling Temp ( ../Temp.hs, ../Temp.o ) ../Temp.hs:4:23: error: * Couldn't match type `Bool' with `a -> Bool' Expected type: Bool -> a -> Bool Actual type: Bool -> Bool * In the first argument of `foldl', namely `(&& (flip $ elem u))' In the expression: foldl (&& (flip $ elem u)) True v In an equation for `isPermut': isPermut u v = foldl (&& (flip $ elem u)) True v * Relevant bindings include v :: [a] (bound at ../Temp.hs:4:12) u :: [a] (bound at ../Temp.hs:4:10) isPermut :: [a] -> [a] -> Bool (bound at ../Temp.hs:4:1) | 4 | isPermut u v = foldl (&& (flip $ elem u)) True v | ^^^^^^^^^^^^^^^^^^ ``` (Broken code taken from Stack Overflow) - - - - - 144abba3 by Ben Gamari at 2019-09-27T22:11:53-04:00 configure: Don't depend upon alex in source dist build This fixes #16860 by verifying that the generated sources don't already exist before asserting that the `alex` executable was found. This replicates the logic already used for `happy` in the case of `alex`. - - - - - c6fb913c by John Ericson at 2019-09-27T22:12:35-04:00 Just get RTS libs from its package conf `rts.conf` already contains this exact information in its `extra-libraries` stanza. - - - - - f07862b4 by Ben Gamari at 2019-09-27T22:13:16-04:00 ghc-prim: Fix documentation of Type As pointed out in #17243, `Type` is not the only kind having values. - - - - - 0201d0bf by chris-martin at 2019-09-27T22:14:00-04:00 Clarify the purpose and status of the GHC.TypeLits module - - - - - 444e554f by chris-martin at 2019-09-27T22:14:00-04:00 Expand description of DataKinds to mention data constructors, and include mention of TypeError - - - - - 1582dafa by Sebastian Graf at 2019-09-27T22:14:44-04:00 PmCheck: Look at precendence to give type signatures to some wildcards Basically do what we currently only do for -XEmptyCase in other cases where adding the type signature won't distract from pattern matches in other positions. We use the precedence to guide us, equating "need to parenthesise" with "too much noise". - - - - - ad0c4390 by Shayne Fletcher at 2019-09-27T22:15:27-04:00 Add test for expected dependencies of 'Parser' - - - - - 0b1fa64d by Ben Gamari at 2019-09-27T22:16:04-04:00 testsuite: Mark cgrun071 as broken on i386 As described in #17247. - - - - - 24620182 by Daniel Gröber at 2019-09-27T22:17:04-04:00 Raise minimum GHC version to 8.6 commit 795986aaf33e ("Remove unneeded CPP now that GHC 8.6 is the minimum") broke the 8.4 build. - - - - - e0bbb961 by Ben Gamari at 2019-09-27T22:17:44-04:00 testsuite: Mark compact_gc as fragile in the ghci way As noted in #17253. - - - - - bb984ac6 by Ben Gamari at 2019-09-27T22:18:42-04:00 testsuite: Mark hs_try_putmvar003 as fragile in threaded1 Due to #16361. Note that I'm leaving out threaded2 since it's not clear whether the single crash in that way was due to other causes. - - - - - ad2a1f99 by Ben Gamari at 2019-09-27T22:19:26-04:00 testsuite: Mark T3389 as broken in profiled ways on i386 As noted in #17256. - - - - - 6f9fa0be by Ben Gamari at 2019-09-27T22:20:04-04:00 testsuite: Mark TH tests as fragile in LLVM built external-interpreter Due to #16087. This drops the previous explicit list of broken tests and rather encompasses the entire set of tests since they all appear to be broken. - - - - - c5d888d4 by Sebastian Graf at 2019-09-28T17:11:41-04:00 PmCheck: No ConLike instantiation in pmcheck `pmcheck` used to call `refineToAltCon` which would refine the knowledge we had about a variable by equating it to a `ConLike` application. Since we weren't particularly smart about this in the Check module, we simply freshened the constructors existential and term binders utimately through a call to `mkOneConFull`. But that instantiation is unnecessary for when we match against a concrete pattern! The pattern will already have fresh binders and field types. So we don't call `refineToAltCon` from `Check` anymore. Subsequently, we can simplify a couple of call sites and functions in `PmOracle`. Also implementing `computeCovered` becomes viable and we don't have to live with the hack that was `addVarPatVecCt` anymore. A side-effect of not indirectly calling `mkOneConFull` anymore is that we don't generate the proper strict argument field constraints anymore. Instead we now desugar ConPatOuts as if they had bangs on their strict fields. This implies that `PmVar` now carries a `HsImplBang` that we need to respect by a (somewhat ephemeral) non-void check. We fix #17234 in doing so. - - - - - ce64b397 by Sebastian Graf at 2019-09-28T17:12:26-04:00 `exprOkForSpeculation` for Note [IO hack in the demand analyser] In #14998 I realised that the notion of speculative execution *exactly matches* eager evaluation of expressions in a case alternative where the scrutinee is an IO action. Normally we have to `deferIO` any result from that single case alternative to prevent this speculative execution, so we had a special case in place in the demand analyser that would check if the scrutinee was a prim-op, in which case we assumed that it would be ok to do the eager evaluation. Now we just check if the scrutinee is `exprOkForSpeculation`, corresponding to the notion that we want to push evaluation of the scrutinee *after* eagerly evaluating stuff from the case alternative. This fixes #14988, because it resolves the last open Item 4 there. - - - - - f3cb8c7c by Ömer Sinan Ağacan at 2019-09-30T22:39:53-04:00 Refactor iface file generation: This commit refactors interface file generation to allow information from the later passed (NCG, STG) to be stored in interface files. We achieve this by splitting interface file generation into two parts: * Partial interfaces, built based on the result of the core pipeline * A fully instantiated interface, which also contains the final fingerprints and can optionally contain information produced by the backend. This change is required by !1304 and !1530. -dynamic-too handling is refactored too: previously when generating code we'd branch on -dynamic-too *before* code generation, but now we do it after. (Original code written by @AndreasK in !1530) Performance ~~~~~~~~~~~ Before this patch interface files where created and immediately flushed to disk which made space leaks impossible. With this change we instead use NFData to force all iface related data structures to avoid space leaks. In the process of refactoring it was discovered that the code in the ToIface Module allocated a lot of thunks which were immediately forced when writing/forcing the interface file. So we made this module more strict to avoid creating many of those thunks. Bottom line is that allocations go down by about ~0.1% compared to master. Residency is not meaningfully different after this patch. Runtime was not benchmarked. Co-Authored-By: Andreas Klebinger <klebinger.andreas at gmx.at> Co-Authored-By: Ömer Sinan Ağacan <omer at well-typed.com> - - - - - 6a1700aa by Simon Peyton Jones at 2019-09-30T22:40:30-04:00 Fix arguments for unbound binders in RULE application We were failing to correctly implement Note [Unbound RULE binders] in Rules.hs. In particular, when cooking up a fake Refl, were were failing to apply the substitition. This patch fixes that problem, and simultaneously tidies up the impedence mis-match between RuleSubst and TCvSubst. Thanks to Sebastian! - - - - - 97811ef5 by Takenobu Tani at 2019-09-30T22:41:35-04:00 Add help message for GHCi :instances command This commit updates GHCi's help message for GHC 8.10. - - - - - 6f8550a3 by Sebastian Graf at 2019-09-30T22:42:14-04:00 Move pattern match checker modules to GHC.HsToCore.PmCheck - - - - - b36dd49b by Takenobu Tani at 2019-09-30T22:42:53-04:00 testsuite: Add minimal test for :doc command Currently, there are no testcases for GHCi `:doc` command. Perhaps because it was experimental. And it could be changed in the future. But `:doc` command is already useful, so I add a minimal regression test to keep current behavior. See also 85309a3cda for implementation of `:doc` command. - - - - - bdba6ac2 by Vladislav Zavialov at 2019-09-30T22:43:31-04:00 Do not rely on CUSKs in 'base' Use standalone kind signatures instead of complete user-specified kinds in Data.Type.Equality and Data.Typeable - - - - - dbdf6a3d by Ben Gamari at 2019-09-30T22:44:07-04:00 testsuite: Mark T3389 as broken in hpc way on i386 See #17256. - - - - - 822481d5 by Ben Gamari at 2019-09-30T22:44:44-04:00 Bump process submodule Marks process003 as fragile, as noted in #17245. - - - - - 6548b7b0 by Sebastian Graf at 2019-10-01T09:22:10+00:00 Add a bunch of testcases for the pattern match checker Adds regression tests for tickets #17207, #17208, #17215, #17216, #17218, #17219, #17248 - - - - - 58013220 by Sebastian Graf at 2019-10-01T09:22:18+00:00 Add testcases inspired by Luke Maranget's pattern match series In his paper "Warnings for Pattern Matching", Luke Maranget describes three series in his appendix for which GHC's pattern match checker scaled very badly. We mostly avoid this now with !1752. This commit adds regression tests for each of the series. Fixes #17264. - - - - - 9c002177 by Ryan Scott at 2019-10-01T16:24:12-04:00 Refactor some cruft in TcDeriv * `mk_eqn_stock`, `mk_eqn_anyclass`, and `mk_eqn_no_mechanism` all took a continuation of type `DerivSpecMechanism -> DerivM EarlyDerivSpec` to represent its primary control flow. However, in practice this continuation was always instantiated with the `mk_originative_eqn` function, so there's not much point in making this be a continuation in the first place. This patch removes these continuations in favor of invoking `mk_originative_eqn` directly, which is simpler. * There were several parts of `TcDeriv` that took different code paths if compiling an `.hs-boot` file. But this is silly, because ever since 101a8c770b9d3abd57ff289bffea3d838cf25c80 we simply error eagerly whenever attempting to derive any instances in an `.hs-boot` file. This patch removes all of the unnecessary `.hs-boot` code paths, leaving only one (which errors out). * Remove various error continuation arguments from `mk_eqn_stock` and related functions. - - - - - 9a27a063 by David Eichmann at 2019-10-01T16:55:33-04:00 Hadrian: Libffi rule now `produces` dynamic library files. - - - - - 0956c194 by David Eichmann at 2019-10-01T16:55:33-04:00 Hadrian: do not cache GHC configure rule - - - - - 8924224e by Ömer Sinan Ağacan at 2019-10-01T16:55:37-04:00 Make small INLINE functions behave properly Simon writes: Currently we check for a type arg rather than isTyCoArg. This in turn makes INLINE things look bigger than they should be, and stops them being inlined into boring contexts when they perfectly well could be. E.g. f x = g <refl> x {-# INLINE g #-} ... (map (f x) xs) ... The context is boring, so don't inline unconditionally. But f's RHS is no bigger than its call, provided you realise that the coercion argument is ultimately cost-free. This happens in practice for $WHRefl. It's not a big deal: at most it means we have an extra function call overhead. But it's untidy, and actually worse than what happens without an INLINE pragma. Fixes #17182 This makes 0.0% change in nofib binary sizes. - - - - - 53b0c6e0 by Gabor Greif at 2019-10-03T08:15:50-04:00 Typo in comment [ci skip] - - - - - 60229e9e by Ryan Scott at 2019-10-03T12:17:10-04:00 Merge TcTypeableValidity into TcTypeable, document treatment of casts This patch: * Implements a refactoring (suggested in https://gitlab.haskell.org/ghc/ghc/merge_requests/1199#note_207345) that moves all functions from `TcTypeableValidity` back to `TcTypeable`, as the former module doesn't really need to live on its own. * Adds `Note [Typeable instances for casted types]` to `TcTypeable` explaining why the `Typeable` solver currently does not support types containing casts. Resolves #16835. - - - - - 3b9d4907 by Richard Eisenberg at 2019-10-03T12:17:13-04:00 Note [Don't flatten tuples from HsSyn] in MkCore Previously, we would sometimes flatten 1-tuples and sometimes not. This didn't cause damage because there is no way to generate HsSyn with 1-tuples. But, with the upcoming fix to #16881, there will be. Without this patch, obscure lint errors would have resulted. No test case, as there is not yet a way to tickle this. - - - - - 8a254d6b by Ömer Sinan Ağacan at 2019-10-03T12:17:19-04:00 Fix new compact block allocation in allocateForCompact allocateForCompact() is called when nursery of a compact region is full, to add new blocks to the compact. New blocks added to an existing region needs a StgCompactNFDataBlock header, not a StgCompactNFData. This fixes allocateForCompact() so that it now correctly allocates space for StgCompactNFDataBlock instead of StgCompactNFData as before. Fixes #17044. A regression test T17044 added. - - - - - 3c7b172b by James Brock at 2019-10-03T12:17:24-04:00 docs String, hyperlink to Data.List Add a reference to the documentation for Data.List in the description for String. On the generated Haddock for Data.String, http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-String.html there is curently no hyperlink to Data.List, which is where a reader will find most of the useful functions which can operate on Strings. I imagine this has confused beginners who came to this page looking for String operations. - - - - - 67bf734c by John Ericson at 2019-10-03T12:17:28-04:00 Add `module {-# SOURCE #-} Foo` syntax for hs-boot in bkp This is a good convenience for testing. - - - - - 6655ec73 by Richard Eisenberg at 2019-10-03T12:17:30-04:00 Improve documentation around empty tuples/lists This patch also changes the way we handle empty lists, simplifying them somewhat. See Note [Empty lists]. Previously, we had to special-case empty lists in the type-checker. Now no more! Finally, this patch improves some documentation around the ir_inst field used in the type-checker. This breaks a test case, but I really think the problem is #17251, not really related to this patch. Test case: typecheck/should_compile/T13680 - - - - - 9a4ff210 by John Ericson at 2019-10-03T12:17:31-04:00 Make Haddock submodule remote point to gitlab mirror This makes it match the others - - - - - cb364bc2 by Ben Gamari at 2019-10-03T12:17:32-04:00 testsuite: Mark print037 as fragile, not broken See #16205. - - - - - 259f4dff by Ben Gamari at 2019-10-03T12:17:32-04:00 Exclude rts.cabal from source distributions This modifies both the Hadrian and make build systems to avoid included the rts.cabal generated by autoconf in the source distribution. Fixes #17265. - - - - - e4c93896 by Ben Gamari at 2019-10-03T12:17:32-04:00 DynFlags: Only warn when split-sections is ignored Previously we would throw an error which seems a bit harsh. As reported in #17283. - - - - - ee6324ad by Tobias Guggenmos at 2019-10-03T12:17:33-04:00 Improve documentation for runtime debugging flags - - - - - 47386fe8 by Tobias Guggenmos at 2019-10-03T12:17:33-04:00 Add new debug flag -DZ Zeros heap memory after gc freed it. - - - - - d0924b15 by Stefan Schulze Frielinghaus at 2019-10-03T12:17:34-04:00 Extend argument of createIOThread to word size Function createIOThread expects its second argument to be of size word. The natural size of the second parameter is 32bits. Thus for some 64bit architectures, where a write of the lower half of a register does not clear the upper half, the value must be zero extended. - - - - - 1357d023 by Ben Gamari at 2019-10-03T12:17:34-04:00 rules/haddock: Ensure that RTS stats directory exists It may not exist if the source tarball was extracted yet not the testsuite tarball. - - - - - ec93d2a9 by Fumiaki Kinoshita at 2019-10-04T21:43:49-04:00 Add Monad instances to `(,,) a b` and `(,,,) a b c` - - - - - 05419e55 by John Ericson at 2019-10-04T21:44:29-04:00 Per stage headers, ghc_boot_platform.h -> stage 0 ghcplatform.h The generated headers are now generated per stage, which means we can skip hacks like `ghc_boot_platform.h` and just have that be the stage 0 header as proper. In general, stages are to be embraced: freely generate everything in each stage but then just build what you depend on, and everything is symmetrical and efficient. Trying to avoid stages because bootstrapping is a mind bender just creates tons of bespoke mini-mind-benders that add up to something far crazier. Hadrian was pretty close to this "stage-major" approach already, and so was fairly easy to fix. Make needed more work, however: it did know about stages so at least there was a scaffold, but few packages except for the compiler cared, and the compiler used its own counting system. That said, make and Hadrian now work more similarly, which is good for the transition to Hadrian. The merits of embracing stage aside, the change may be worthy for easing that transition alone. - - - - - 75a5dd8e by John Ericson at 2019-10-04T21:44:29-04:00 Remove {Build,Host}Platform_NAME from header They are only used in a file we construct directly, so just skip CPP. - - - - - b538476b by Daroc Alden at 2019-10-04T21:45:09-04:00 Deprecate -fwarn-hi-shadowing, because it was never implemented and is not used. This fixes #10913. - - - - - dd8f76b2 by John Ericson at 2019-10-04T21:45:48-04:00 Factor out a smaller part of Platform for host fallback - - - - - d15b44d6 by John Ericson at 2019-10-04T21:45:49-04:00 Pull out the settings file parsing code into it's own module. This has two benefits: 1. One less hunk of code dependent on DynFlags 2. Add a little bit of error granularity to distrinugish between missing data and bad data. This could someday be shared with ghc-pkg which aims to work even with a missing file. I also am about to to make --supported-extensions use this too. - - - - - eb892b28 by John Ericson at 2019-10-04T21:45:49-04:00 Add tryFindTopDir to look for the top dir without blowing up if it is not found. - - - - - 0dded5ec by John Ericson at 2019-10-04T21:45:49-04:00 Always enable the external interpreter You can always just not use or even build `iserv`. I don't think the maintenance cost of the CPP is worth...I can't even tell what the benefit is. - - - - - 0d31ccdd by Artem Pyanykh at 2019-10-04T21:46:28-04:00 [linker, macho] Don't map/allocate zero size sections and segments Zero size sections are common even during regular build on MacOS. For instance: ``` $ ar -xv libHSghc-prim-0.6.1.a longlong.o $ otool -l longlong.o longlong.o: Mach header magic cputype cpusubtype caps filetype ncmds sizeofcmds flags 0xfeedfacf 16777223 3 0x00 1 2 176 0x00002000 Load command 0 cmd LC_SEGMENT_64 cmdsize 152 segname vmaddr 0x0000000000000000 vmsize 0x0000000000000000 <-- segment size = 0 fileoff 208 filesize 0 maxprot 0x00000007 initprot 0x00000007 nsects 1 flags 0x0 Section sectname __text segname __TEXT addr 0x0000000000000000 size 0x0000000000000000 <-- section size = 0 offset 208 align 2^0 (1) reloff 0 nreloc 0 flags 0x80000000 reserved1 0 reserved2 0 cmd LC_BUILD_VERSION cmdsize 24 platform macos sdk 10.14 minos 10.14 ntools 0 ``` The issue of `mmap`ing 0 bytes was resolved in !1050, but the problem remained. These 0 size segments and sections were still allocated in object code, which lead to failed `ASSERT(size > 0)` in `addProddableBlock` further down the road. With this change zero size segments **and** sections are not mapped/allocated at all. Test plan: 1. Build statically linked GHC. 2. Run `ghc --interactive`. Observe that REPL loads successfully (which was not the case before). 3. Load several more compiled hs files into repl. No failures. - - - - - 93f02b62 by Roland Senn at 2019-10-04T21:47:07-04:00 New fix for #11647. Avoid side effects like #17171 If a main module doesn't contain a header, we omit the check whether the main module is exported. With this patch GHC, GHCi and runghc use the same code. - - - - - 8039b625 by Matthew Bauer at 2019-10-04T21:47:47-04:00 Add musl systems to llvm-targets This was done in Nixpkgs, but never upstreamed. Musl is pretty much the same as gnu, but with a different libc. I’ve used the same values for everything. - - - - - ee8118ca by John Ericson at 2019-10-05T00:11:58-04:00 Clean up `#include`s in the compiler - Remove unneeded ones - Use <..> for inter-package. Besides general clean up, helps distinguish between the RTS we link against vs the RTS we compile for. - - - - - 241921a0 by Ben Gamari at 2019-10-05T19:18:40-04:00 rts: Fix CNF dirtying logic Previously due to a silly implementation bug CNFs would never have their dirty flag set, resulting in their being added again and again to the `mut_list`. Fix this. Fixes #17297. - - - - - 825c108b by Ryan Scott at 2019-10-07T12:00:59-04:00 Only flatten up to type family arity in coreFlattenTyFamApp (#16995) Among other uses, `coreFlattenTyFamApp` is used by Core Lint as a part of its check to ensure that each type family axiom reduces according to the way it is defined in the source code. Unfortunately, the logic that `coreFlattenTyFamApp` uses to flatten type family applications disagreed with the logic in `TcFlatten`, which caused it to spuriously complain this program: ```hs type family Param :: Type -> Type type family LookupParam (a :: Type) :: Type where LookupParam (f Char) = Bool LookupParam x = Int foo :: LookupParam (Param ()) foo = 42 ``` This is because `coreFlattenTyFamApp` tries to flatten the `Param ()` in `LookupParam (Param ())` to `alpha` (where `alpha` is a flattening skolem), and GHC is unable to conclude that `alpha` is apart from `f Char`. This patch spruces up `coreFlattenTyFamApp` so that it instead flattens `Param ()` to `alpha ()`, which GHC _can_ know for sure is apart from `f Char`. See `Note [Flatten], wrinkle 3` in `FamInstEnv`. - - - - - b2577081 by Ben Gamari at 2019-10-07T12:01:46-04:00 Refactor, document, and optimize LLVM configuration loading As described in the new Note [LLVM Configuration] in SysTools, we now load llvm-targets and llvm-passes lazily to avoid the overhead of doing so when -fllvm isn't used (also known as "the common case"). Noticed in #17003. Metric Decrease: T12234 T12150 - - - - - 93c71ae6 by Ben Gamari at 2019-10-07T12:02:23-04:00 configure: Determine library versions of template-haskell, et al. These are needed by the user guide documentation. Fixes #17260. - - - - - b7890611 by Andrey Mokhov at 2019-10-07T12:03:13-04:00 Hadrian: Stop using in-tree Cabal - - - - - 0ceb98f6 by Andrey Mokhov at 2019-10-07T12:03:13-04:00 Switch to cabal-version=3.0 in ghc-heap.cabal - - - - - e3418e96 by Andrey Mokhov at 2019-10-07T12:03:13-04:00 Switch to cabal-version=3.0 in base.cabal and rts.cabal - - - - - 805653f6 by John Ericson at 2019-10-07T12:04:19-04:00 Get rid of wildcard patterns in prim Cmm emitting code This way, we can be sure we don't miss a case. - - - - - ab945819 by Ryan Scott at 2019-10-07T12:05:09-04:00 Refactor some cruft in TcGenGenerics * `foldBal` contains needless partiality that can easily be avoided. * `mkProd_E` and `mkProd_P` both contain unique supply arguments that are completely unused, which can be removed. - - - - - d0edba3a by John Ericson at 2019-10-07T12:05:47-04:00 Remove CONFIGURE_ARGS from configure.ac It looks like it's been unused since at least 34cc75e1a62638f2833815746ebce0a9114dc26b. - - - - - 9a6bfb0a by John Ericson at 2019-10-07T12:06:26-04:00 Keep OSTYPE local to configure.ac Unused outside it since b6be81b841e34ca45b3549c4c79e886a8761e59a. - - - - - 4df39fd0 by John Ericson at 2019-10-07T12:07:08-04:00 Get rid of GHC_PACKAGE_DB_FLAG We no longer support booting from older GHC since 527bcc41630918977c73584d99125ff164400695. - - - - - 31a29a7a by John Ericson at 2019-10-07T12:07:46-04:00 Remove GhcLibsWithUnix d679ca43e7477284d733b94ff542be5363be3353 meant to remove it but did not finish the job. - - - - - 77ca39e3 by Ben Gamari at 2019-10-08T05:11:03-04:00 gitlab-ci: Add missing TEST_ENV variables This should fix #16985. - - - - - 9a2798e1 by Ben Gamari at 2019-10-08T05:11:03-04:00 hadrian: Add `validate` and `slow validate` flavours - - - - - ab311696 by Ben Gamari at 2019-10-08T05:11:03-04:00 validate: Use Hadrian's validate flavour - - - - - 98179a77 by Ben Gamari at 2019-10-08T05:11:03-04:00 gitlab-ci: Use validate flavour in hadrian builds - - - - - 8af9eba8 by Ben Gamari at 2019-10-08T05:11:40-04:00 base: Document the fact that Typeable is automatically "derived" This fixes #17060. - - - - - 397c6ed5 by Sebastian Graf at 2019-10-08T05:12:15-04:00 PmCheck: Identify some semantically equivalent expressions By introducing a `CoreMap Id` to the term oracle, we can represent syntactically equivalent expressions by the same `Id`. Combine that with `CoreOpt.simpleCoreExpr` and it might even catch non-trivial semantic equalities. Unfortunately due to scoping issues, this will not solve #17208 for view patterns yet. - - - - - 8a2e8408 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Refer to language extension flags via :extension: Previously several were referred to via :ghc-flag:`-X...`. - - - - - 7cd54538 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Make reverse flags addressable via :ghc-flag: Previously one could not easily link to the :reverse: flag of a ghc-flag. - - - - - e9813afc by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Document -XHaskell98 and -XHaskell2010 - - - - - eaeb28a1 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Fix various warnings - - - - - 180cf177 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Document NondecreasingIndentation - - - - - 0a26f9e8 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Document -fworker-wrapper - - - - - ca4791db by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Rework pragma key generation Previously we had a hack to handle the case of multi-token SPECIALISE pragmas. Now we use a slightly more general rule of using a prefix of tokens containing only alphabetical characters. - - - - - 98c09422 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Run sphinx in nit-picky mode This ensure that it blurts an error on missing references. - - - - - a95f7185 by Ben Gamari at 2019-10-08T05:12:58-04:00 doc: Write out documented flag list - - - - - 9402608e by Ben Gamari at 2019-10-08T05:12:58-04:00 gitlab-ci: Check coverage of GHC flags in users guide This ensures that all GHC flags are documented during the documentation build. Fixes #17315. - - - - - 9ac3bcbb by Andrew Martin at 2019-10-08T13:24:52-04:00 Document the UnliftedFFITypes extension. - - - - - 77f3ba23 by Andrew Martin at 2019-10-08T13:24:52-04:00 Rephrase a bunch of things in the unlifted ffi types documentation. Add a section on pinned byte arrays. - - - - - a70db7bf by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] link to foreign cmm call - - - - - 0d413259 by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] make the table better - - - - - 0c7a5bcd by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] can not -> may not - - - - - 6a5c249d by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] clarify what unsound means - - - - - bf02c264 by Ryan Scott at 2019-10-08T13:25:37-04:00 Mark newtype constructors as used in the Coercible solver (#10347) Currently, newtype constructors are not marked as used when they are accessed under the hood by uses of `coerce`, as described in #10347. This fixes #10347 by co-opting the `tcg_keep` field of `TcGblEnv` to track uses of newtype constructors in the `Coercible` solver. See `Note [Tracking unused binding and imports]` in `TcRnTypes`. Since #10347 is fixed, I was able to simplify the code in `TcDeriv` slightly, as the hack described in `Note [Newtype deriving and unused constructors]` is no longer necessary. - - - - - 9612e91c by Richard Eisenberg at 2019-10-08T13:26:20-04:00 Solve constraints from top-level groups sooner Previously, all constraints from all top-level groups (as separated by top-level splices) were lumped together and solved at the end. This could leak metavariables to TH, though, and that's bad. This patch solves each group's constraints before running the next group's splice. Naturally, we now report fewer errors in some cases. One nice benefit is that this also fixes #11680, but in a much simpler way than the original fix for that ticket. Admittedly, the error messages degrade just a bit from the fix from #11680 (previously, we informed users about variables that will be brought into scope below a top-level splice, and now we just report an out-of-scope error), but the amount of complexity required throughout GHC to get that error was just not worth it. This patch thus reverts much of f93c9517a2c6e158e4a5c5bc7a3d3f88cb4ed119. Fixes #16980 Test cases: th/T16980{,a} - - - - - c2d4011c by Vladislav Zavialov at 2019-10-08T13:27:12-04:00 Bump array and haddock submodules - - - - - f691f0c2 by Sebastian Graf at 2019-10-08T13:27:49-04:00 PmCheck: Look up parent data family TyCon when populating `PossibleMatches` The vanilla COMPLETE set is attached to the representation TyCon of a data family instance, whereas the user-defined COMPLETE sets are attached to the parent data family TyCon itself. Previously, we weren't trying particularly hard to get back to the representation TyCon to the parent data family TyCon, resulting in bugs like #17207. Now we should do much better. Fixes the original issue in #17207, but I found another related bug that isn't so easy to fix. - - - - - 0c0a15a8 by Ben Gamari at 2019-10-09T16:21:14-04:00 Rename STAGE macro to GHC_STAGE To avoid polluting the macro namespace - - - - - 63a5371d by Ben Gamari at 2019-10-09T16:21:14-04:00 Relayout generated header body - - - - - 817c1a94 by Ben Gamari at 2019-10-09T16:21:14-04:00 Define GHC_STAGE in headers instead of command-line - - - - - 5f2c49d8 by Ben Gamari at 2019-10-09T16:21:14-04:00 Remove GHC_STAGE guards from MachDeps This allows the stage1 compiler (which needs to run on the build platform and produce code for the host) to depend upon properties of the target. This is wrong. However, it's no more wrong than it was previously and @Erichson2314 is working on fixing this so I'm going to remove the guard so we can finally bootstrap HEAD with ghc-8.8 (see issue #17146). - - - - - 35cc5eff by Ben Gamari at 2019-10-09T16:21:15-04:00 Test - - - - - d584e3f0 by Ryan Scott at 2019-10-09T16:21:50-04:00 Use addUsedDataCons more judiciously in TcDeriv (#17324) If you derive an instance like this: ```hs deriving <...> instance Foo C ``` And the data constructors for `C` aren't in scope, then `doDerivInstErrorChecks1` throws an error. Moreover, it will _only_ throw an error if `<...>` is either `stock` or `newtype`. This is because the code that the `anyclass` or `via` strategies would generate would not require the use of the data constructors for `C`. However, `doDerivInstErrorChecks1` has another purpose. If you write this: ```hs import M (C(MkC1, ..., MkCn)) deriving <...> instance Foo C ``` Then `doDerivInstErrorChecks1` will call `addUsedDataCons` on `MkC1` through `MkCn` to ensure that `-Wunused-imports` does not complain about them. However, `doDerivInstErrorChecks1` was doing this for _every_ deriving strategy, which mean that if `<...>` were `anyclass` or `via`, then the warning about `MkC1` through `MkCn` being unused would be suppressed! The fix is simple enough: only call `addUsedDataCons` when the strategy is `stock` or `newtype`, just like the other code paths in `doDerivInstErrorChecks1`. Fixes #17324. - - - - - 30f5ac07 by Sebastian Graf at 2019-10-11T22:10:12-04:00 Much simpler language for PmCheck Simon realised that the simple language composed of let bindings, bang patterns and flat constructor patterns is enough to capture the semantics of the source pattern language that are important for pattern-match checking. Well, given that the Oracle is smart enough to connect the dots in this less informationally dense form, which it is now. So we transform `translatePat` to return a list of `PmGrd`s relative to an incoming match variable. `pmCheck` then trivially translates each of the `PmGrd`s into constraints that the oracle understands. Since we pass in the match variable, we incidentally fix #15884 (coverage checks for view patterns) through an interaction with !1746. - - - - - 166e1c2a by Stefan Schulze Frielinghaus at 2019-10-11T22:10:51-04:00 Hadrian: Take care of assembler source files Fixes #17286. - - - - - c2290596 by John Ericson at 2019-10-12T06:32:18-04:00 Simplify Configure in a few ways - No need to distinguish between gcc-llvm and clang. First of all, gcc-llvm is quite old and surely unmaintained by now. Second of all, none of the code actually care about that distinction! Now, it does make sense to consider C multiple frontends for LLVMs in the form of clang vs clang-cl (same clang, yes, but tweaked interface). But this is better handled in terms of "gccish vs mvscish" and "is LLVM", yielding 4 combinations. Therefore, I don't think it is useful saving the existing code for that. - Get the remaining CC_LLVM_BACKEND, and also TABLES_NEXT_TO_CODE in mk/config.h the normal way, rather than hacking it post-hoc. No point keeping these special cases around for now reason. - Get rid of hand-rolled `die` function and just use `AC_MSG_ERROR`. - Abstract check + flag override for unregisterised and tables next to code. Oh, and as part of the above I also renamed/combined some variables where it felt appropriate. - GccIsClang -> CcLlvmBackend. This is for `AC_SUBST`, like the other Camal case ones. It was never about gcc-llvm, or Apple's renamed clang, to be clear. - llvm_CC_FLAVOR -> CC_LLVM_BACKEND. This is for `AC_DEFINE`, like the other all-caps snake case ones. llvm_CC_FLAVOR was just silly indirection *and* an odd name to boot. - - - - - f1ce3535 by Vladislav Zavialov at 2019-10-12T06:33:05-04:00 Escape stats file command (#13676) - - - - - cd1a8808 by Vladislav Zavialov at 2019-10-12T06:33:05-04:00 Skip T13767 on Darwin The CI job fails with: +++ rts/T13676.run/T13676.run.stderr.normalised 2019-10-09 12:27:56.000000000 -0700 @@ -0,0 +1,4 @@ +dyld: Library not loaded: @rpath/libHShaskeline-0.7.5.0-ghc8.9.0.20191009.dylib + Referenced from: /Users/builder/builds/ewzE5N2p/0/ghc/ghc/inplace/lib/bin/ghc + Reason: image not found +*** Exception: readCreateProcess: '/Users/builder/builds/ewzE5N2p/0/ghc/ghc/inplace/lib/bin/ghc' '-B/Users/builder/builds/ewzE5N2p/0/ghc/ghc/inplace/lib' '-e' ''/''$'/'' == '/''/x0024'/''' +RTS '-tT13676.t' (exit -6): failed Unable to reproduce locally. - - - - - 0a338264 by Ryan Scott at 2019-10-12T06:33:42-04:00 Use newDFunName for both manual and derived instances (#17339) Issue #17339 was caused by using a slightly different version of `newDFunName` for derived instances that, confusingly enough, did not take all arguments to the class into account when generating the `DFun` name. I cannot think of any good reason for doing this, so this patch uses `newDFunName` uniformly for both derived instances and manually written instances alike. Fixes #17339. - - - - - c50e4c92 by Simon Peyton Jones at 2019-10-12T13:35:24-04:00 Fix validity checking for inferred types GHC is suposed to uphold the principle that an /inferred/ type for a let-binding should obey the rules for that module. E.g. we should only accept an inferred higher rank type if we have RankNTypes on. But we were failing to check this: TcValidity.checkValidType allowed arbitrary rank for inferred types. This patch fixes the bug. It might in principle cause some breakage, but if so that's good: the user should add RankNTypes and/or a manual signature. (And almost every package has explicit user signatures for all top-level things anyway.) Let's see. Fixes #17213. Metric Decrease: T10370 - - - - - 226d86d2 by Simon Peyton Jones at 2019-10-12T13:36:02-04:00 Do not add a 'solved dict' for quantified constraints GHC has a wonderful-but-delicate mechanism for building recursive dictionaries by adding a goal to the "solved dictionaries" before solving the sub-goals. See Note [Solved dictionaries] in TcSMonad Ticket #17267 showed that if you use this mechanism for local /quantified/ constraints you can get a loop -- or even unsafe coerce. This patch fixes the bug. Specifically * Make TcSMonad.addSolvedDict be conditional on using a /top level/ instance, not a quantified one. * Moreover, we /also/ don't want to add a solved dict for equalities (a~b). * Add lots more comments to Note [Solved dictionaries] to explain the above cryptic stuff. * Extend InstanceWhat to identify those strange built-in equality instances. A couple of other things along the way * Delete the unused Type.isIPPred_maybe. * Stop making addSolvedDict conditional on not being an impolicit parameter. This comes from way back. But it's irrelevant now because IP dicts are never solved via an instance. - - - - - 5ab1a28d by nineonine at 2019-10-13T06:31:40-04:00 Template Haskell: make unary tuples legal (#16881) - - - - - c1bd07cd by Andreas Klebinger at 2019-10-13T06:32:19-04:00 Fix #17334 where NCG did not properly update the CFG. Statements can change the basic block in which instructions are placed during instruction selection. We have to keep track of this switch of the current basic block as we need this information in order to properly update the CFG. This commit implements this change and fixes #17334. We do so by having stmtToInstr return the new block id if a statement changed the basic block. - - - - - 1eda9f28 by Takenobu Tani at 2019-10-13T19:06:02-04:00 users-guide: Add GHCi's ::<builtin-command> form This commit explicitly adds description about double colon command of GHCi. [skip ci] - - - - - 27145351 by Takenobu Tani at 2019-10-13T19:06:40-04:00 Add GHCi help message for :def! and :: commands - - - - - 78463fc5 by Ryan Scott at 2019-10-14T08:38:36-04:00 Add docs/users_guide/.log to .gitignore When the users guide fails to build (as in #17346), a `docs/users_guide/.log` file will be generated with contents that look something like this: ``` WARNING: unknown config value 'latex_paper_size' in override, ignoring /home/rgscott/Software/ghc5/docs/users_guide/ghci.rst:3410: WARNING: u'ghc-flag' reference target not found: -pgmo ?option? /home/rgscott/Software/ghc5/docs/users_guide/ghci.rst:3410: WARNING: u'ghc-flag' reference target not found: -pgmo ?port? Encoding error: 'ascii' codec can't encode character u'\u27e8' in position 132: ordinal not in range(128) The full traceback has been saved in /tmp/sphinx-err-rDF2LX.log, if you want to report the issue to the developers. ``` This definitely should not be checked in to version control, so let's add this to `.gitignore`. - - - - - 4aba72d6 by Ryan Scott at 2019-10-14T08:39:12-04:00 Mention changes from #16980, #17213 in 8.10.1 release notes The fixes for these issues both have user-facing consequences, so it would be good to mention them in the release notes for GHC 8.10.1. While I'm in town, also mention `UnboxedSums` in the release notes entry related to `-fobject-code`. - - - - - 0ca044fd by Ben Gamari at 2019-10-14T08:39:48-04:00 gitlab-ci: Move hadrian-ghc-in-ghci job first This is a very cheap job and can catch a number of "easy" failure modes (e.g. missing imports in the compiler). Let's run it first. - - - - - a2d3594c by Ryan Scott at 2019-10-15T01:35:34-04:00 Refactor some cruft in TcDerivInfer.inferConstraints The latest installment in my quest to clean up the code in `TcDeriv*`. This time, my sights are set on `TcDerivInfer.inferConstraints`, which infers the context for derived instances. This function is a wee bit awkward at the moment: * It's not terribly obvious from a quick glance, but `inferConstraints` is only ever invoked when using the `stock` or `anyclass` deriving strategies, as the code for inferring the context for `newtype`- or `via`-derived instances is located separately in `mk_coerce_based_eqn`. But there's no good reason for things to be this way, so I moved this code from `mk_coerce_based_eqn` to `inferConstraints` so that everything related to inferring instance contexts is located in one place. * In this process, I discovered that the Haddocks for the auxiliary function `inferConstraintsDataConArgs` are completely wrong. It claims that it handles both `stock` and `newtype` deriving, but this is completely wrong, as discussed above—it only handles `stock`. To rectify this, I renamed this function to `inferConstraintsStock` to reflect its actual purpose and created a new `inferConstraintsCoerceBased` function to specifically handle `newtype` (and `via`) deriving. Doing this revealed some opportunities for further simplification: * Removing the context-inference–related code from `mk_coerce_based_eqn` made me realize that the overall structure of the function is basically identical to `mk_originative_eqn`. In fact, I was easily able to combine the two functions into a single `mk_eqn_from_mechanism` function. As part of this merger, I now invoke `atf_coerce_based_error_checks` from `doDerivInstErrorChecks1`. * I discovered that GHC defined this function: ```hs typeToTypeKind = liftedTypeKind `mkVisFunTy` liftedTypeKind ``` No fewer than four times in different modules. I consolidated all of these definitions in a single location in `TysWiredIn`. - - - - - 426b0ddc by Ryan Scott at 2019-10-15T01:36:14-04:00 Don't skip validity checks for built-in classes (#17355) Issue #17355 occurred because the control flow for `TcValidity.check_valid_inst_head` was structured in such a way that whenever it checked a special, built-in class (like `Generic` or `HasField`), it would skip the most important check of all: `checkValidTypePats`, which rejects nonsense like this: ```hs instance Generic (forall a. a) ``` This fixes the issue by carving out `checkValidTypePats` from `check_valid_inst_head` so that `checkValidTypePats` is always invoked. `check_valid_inst_head` has also been renamed to `check_special_inst_head` to reflect its new purpose of _only_ checking for instances headed by special classes. Fixes #17355. - - - - - a55b8a65 by Alp Mestanogullari at 2019-10-15T18:41:18-04:00 iface: export a few more functions from BinIface - - - - - 9c11f817 by Ben Gamari at 2019-10-15T18:41:54-04:00 hadrian: Add support for bindist compressors other than Xz Fixes #17351. - - - - - 535a88e1 by klebinger.andreas at gmx.at at 2019-10-16T07:04:21-04:00 Add loop level analysis to the NCG backend. For backends maintaining the CFG during codegen we can now find loops and their nesting level. This is based on the Cmm CFG and dominator analysis. As a result we can estimate edge frequencies a lot better for methods, resulting in far better code layout. Speedup on nofib: ~1.5% Increase in compile times: ~1.9% To make this feasible this commit adds: * Dominator analysis based on the Lengauer-Tarjan Algorithm. * An algorithm estimating global edge frequences from branch probabilities - In CFG.hs A few static branch prediction heuristics: * Expect to take the backedge in loops. * Expect to take the branch NOT exiting a loop. * Expect integer vs constant comparisons to be false. We also treat heap/stack checks special for branch prediction to avoid them being treated as loops. - - - - - cc2bda50 by adithyaov at 2019-10-16T07:05:01-04:00 Compiling with -S and -fno-code no longer panics (fixes #17143) - - - - - 19641957 by Takenobu Tani at 2019-10-16T07:05:41-04:00 testsuite: Add test for #8305 This is a test for the current algorithm of GHCi command name resolution. I add this test in preparation for updating GHCi command name resolution. For the current algorithm, see https://downloads.haskell.org/ghc/latest/docs/html/users_guide/ghci.html#the-ghci-files - - - - - 6ede3554 by Sebastian Graf at 2019-10-16T07:06:20-04:00 Infer rho-types instead of sigma-types in guard BindStmts and TransStmts In #17343 we saw that we didn't handle the pattern guard `!_ <- undefined` correctly: The `undefined` was never evaluated. Indeed, elaboration failed to insert the invisible type aruments to `undefined`. So `undefined` was trivially a normal-form and in turn never entered. The problem is that we used to infer a sigma-type for the RHS of the guard, the leading qualifiers of which will never be useful in a pattern match situation. Hence we infer a rho-type now. Fixes #17343. - - - - - 798037a1 by John Ericson at 2019-10-16T07:06:58-04:00 Delete ghctags cabal file It came back to life in 381c3ae31b68019177f1cd20cb4da2f9d3b7d6c6 by mistake. - - - - - 51fad9e6 by Richard Eisenberg at 2019-10-16T15:58:58-04:00 Break up TcRnTypes, among other modules. This introduces three new modules: - basicTypes/Predicate.hs describes predicates, moving this logic out of Type. Predicates don't really exist in Core, and so don't belong in Type. - typecheck/TcOrigin.hs describes the origin of constraints and types. It was easy to remove from other modules and can often be imported instead of other, scarier modules. - typecheck/Constraint.hs describes constraints as used in the solver. It is taken from TcRnTypes. No work other than module splitting is in this patch. This is the first step toward homogeneous equality, which will rely more strongly on predicates. And homogeneous equality is the next step toward a dependently typed core language. - - - - - 11d4fc50 by Ben Gamari at 2019-10-16T15:59:52-04:00 hadrian: Introduce enableDebugInfo flavour transformer Also refactor things a bit to eliminate repetition. - - - - - deb96399 by Ryan Scott at 2019-10-16T16:00:29-04:00 Make Coverage.TM a newtype - - - - - 42ebc3f6 by Brian Wignall at 2019-10-16T16:01:06-04:00 Add hyperlinks to PDF/HTML documentation; closes #17342 - - - - - b15a7fb8 by Ben Gamari at 2019-10-17T01:03:11-04:00 testsuite: Ensure that makefile tests get run Previously `makefile_test` and `run_command` tests could easily end up in a situation where they wouldn't be run if the user used the `only_ways` modifier. The reason is to build the set of a ways to run the test in we first start with a candidate set determined by the test type (e.g. `makefile_test`, `compile_run`, etc.) and then filter that set with the constraints given by the test's modifiers. `makefile_test` and `run_command` tests' candidate sets were simply `{normal}`, and consequently most uses of `only_ways` would result in the test being never run. To avoid this we rather use all ways as the candidate sets for these test types. This may result in a few more testcases than we would like (given that some `run_command` tests are insensitive to way) but this can be fixed by adding modifiers and we would much rather run too many tests than too few. This fixes #16042 and a number of other tests afflicted by the same issue. However, there were a few cases that required special attention: * `T14028` is currently failing and is therefore marked as broken due to #17300 * `T-signals-child` is fragile in the `threaded1` and `threaded2` ways (tracked in #17307) - - - - - 4efdda90 by Richard Eisenberg at 2019-10-17T01:03:51-04:00 Tiny fixes to comments around flattening. - - - - - c4c9904b by Ben Gamari at 2019-10-17T01:04:26-04:00 testsuite: Assert that testsuite ways are known This ensures that all testsuite way names given to `omit_ways`, `only_ways`, etc. are known ways. - - - - - 697be2b6 by Ömer Sinan Ağacan at 2019-10-18T15:26:53-04:00 rts/GC: Add an obvious assertion during block initialization Namely ensure that block descriptors are initialized with valid generation numbers. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 61d2ed42 by Ben Gamari at 2019-10-18T15:26:53-04:00 rts: Add Note explaining applicability of selector optimisation depth limit This was slightly non-obvious so a note seems deserved. - - - - - 11395037 by Ben Gamari at 2019-10-18T15:26:53-04:00 rts/Capability: A few documentation comments - - - - - 206f782a by Ben Gamari at 2019-10-18T15:26:53-04:00 rts: Give stack flags proper macros This were previously quite unclear and will change a bit under the non-moving collector so let's clear this up now. - - - - - 81d4675e by Ben Gamari at 2019-10-18T15:26:53-04:00 rts/GC: Refactor gcCAFs - - - - - 4d674c4e by Ben Gamari at 2019-10-18T15:26:53-04:00 rts: Fix macro parenthesisation - - - - - bfcafd39 by Ben Gamari at 2019-10-18T15:27:42-04:00 rts/Schedule: Allow synchronization without holding a capability The concurrent mark-and-sweep will be performed by a GHC task which will not hold a capability. This is necessary to avoid a concurrent mark from interfering with minor generation collections. However, the major collector must synchronize with the mutators at the end of marking to flush their update remembered sets. This patch extends the `requestSync` mechanism used to synchronize garbage collectors to allow synchronization without holding a capability. This change is fairly straightforward as the capability was previously only required for two reasons: 1. to ensure that we don't try to re-acquire a capability that we the sync requestor already holds. 2. to provide a way to suspend and later resume the sync request if there is already a sync pending. When synchronizing without holding a capability we needn't worry about consideration (1) at all. (2) is slightly trickier and may happen, for instance, when a capability requests a minor collection and shortly thereafter the non-moving mark thread requests a post-mark synchronization. In this case we need to ensure that the non-moving mark thread suspends his request until after the minor GC has concluded to avoid dead-locking. For this we introduce a condition variable, `sync_finished_cond`, which a non-capability-bearing requestor will wait on and which is signalled after a synchronization or GC has finished. - - - - - 921e4e36 by Ömer Sinan Ağacan at 2019-10-18T15:27:56-04:00 rts/BlockAlloc: Allow aligned allocation requests This implements support for block group allocations which are aligned to an integral number of blocks. This will be used by the nonmoving garbage collector, which uses the block allocator to allocate the segments which back its heap. These segments are a fixed number of blocks in size, with each segment being aligned to the segment size boundary. This allows us to easily find the segment metadata stored at the beginning of the segment. - - - - - 4b431f33 by Tamar Christina at 2019-10-20T16:21:10+01:00 Windows: Update tarballs to GCC 9.2 and remove MAX_PATH limit. - - - - - 8057ac96 by Ben Gamari at 2019-10-20T21:15:14-04:00 Merge branches 'wip/gc/sync-without-capability' and 'wip/gc/aligned-block-allocation' into wip/gc/preparation - - - - - 32500f64 by Ömer Sinan Ağacan at 2019-10-20T21:15:37-04:00 rts/StableName: Expose FOR_EACH_STABLE_NAME, freeSnEntry, SNT_size These will be needed when we implement sweeping in the nonmoving collector. - - - - - 4be5152a by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Disable aggregate-return warnings from gcc This warning is a bit of a relic; there is little reason to avoid aggregate return values in 2019. - - - - - 04471c4f by Ömer Sinan Ağacan at 2019-10-20T21:15:37-04:00 rts/Scav: Expose scavenging functions To keep the non-moving collector nicely separated from the moving collector its scavenging phase will live in another file, `NonMovingScav.c`. However, it will need to use these functions so let's expose them. - - - - - 6ff29c06 by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Introduce flag to enable the nonmoving old generation This flag will enable the use of a non-moving oldest generation. - - - - - b3ef2d1a by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Introduce debug flag for non-moving GC - - - - - 68e0647f by Ömer Sinan Ağacan at 2019-10-20T21:15:37-04:00 rts: Non-concurrent mark and sweep This implements the core heap structure and a serial mark/sweep collector which can be used to manage the oldest-generation heap. This is the first step towards a concurrent mark-and-sweep collector aimed at low-latency applications. The full design of the collector implemented here is described in detail in a technical note B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell Compiler" (2018) The basic heap structure used in this design is heavily inspired by K. Ueno & A. Ohori. "A fully concurrent garbage collector for functional programs on multicore processors." /ACM SIGPLAN Notices/ Vol. 51. No. 9 (presented by ICFP 2016) This design is intended to allow both marking and sweeping concurrent to execution of a multi-core mutator. Unlike the Ueno design, which requires no global synchronization pauses, the collector introduced here requires a stop-the-world pause at the beginning and end of the mark phase. To avoid heap fragmentation, the allocator consists of a number of fixed-size /sub-allocators/. Each of these sub-allocators allocators into its own set of /segments/, themselves allocated from the block allocator. Each segment is broken into a set of fixed-size allocation blocks (which back allocations) in addition to a bitmap (used to track the liveness of blocks) and some additional metadata (used also used to track liveness). This heap structure enables collection via mark-and-sweep, which can be performed concurrently via a snapshot-at-the-beginning scheme (although concurrent collection is not implemented in this patch). The mark queue is a fairly straightforward chunked-array structure. The representation is a bit more verbose than a typical mark queue to accomodate a combination of two features: * a mark FIFO, which improves the locality of marking, reducing one of the major overheads seen in mark/sweep allocators (see [1] for details) * the selector optimization and indirection shortcutting, which requires that we track where we found each reference to an object in case we need to update the reference at a later point (e.g. when we find that it is an indirection). See Note [Origin references in the nonmoving collector] (in `NonMovingMark.h`) for details. Beyond this the mark/sweep is fairly run-of-the-mill. [1] R. Garner, S.M. Blackburn, D. Frampton. "Effective Prefetch for Mark-Sweep Garbage Collection." ISMM 2007. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - c7e73d12 by Ben Gamari at 2019-10-20T21:15:37-04:00 testsuite: Add nonmoving WAY This simply runs the compile_and_run tests with `-xn`, enabling the nonmoving oldest generation. - - - - - f8f77a07 by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Mark binder as const - - - - - bd8e3ff4 by Ben Gamari at 2019-10-20T21:15:52-04:00 rts: Implement concurrent collection in the nonmoving collector This extends the non-moving collector to allow concurrent collection. The full design of the collector implemented here is described in detail in a technical note B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell Compiler" (2018) This extension involves the introduction of a capability-local remembered set, known as the /update remembered set/, which tracks objects which may no longer be visible to the collector due to mutation. To maintain this remembered set we introduce a write barrier on mutations which is enabled while a concurrent mark is underway. The update remembered set representation is similar to that of the nonmoving mark queue, being a chunked array of `MarkEntry`s. Each `Capability` maintains a single accumulator chunk, which it flushed when it (a) is filled, or (b) when the nonmoving collector enters its post-mark synchronization phase. While the write barrier touches a significant amount of code it is conceptually straightforward: the mutator must ensure that the referee of any pointer it overwrites is added to the update remembered set. However, there are a few details: * In the case of objects with a dirty flag (e.g. `MVar`s) we can exploit the fact that only the *first* mutation requires a write barrier. * Weak references, as usual, complicate things. In particular, we must ensure that the referee of a weak object is marked if dereferenced by the mutator. For this we (unfortunately) must introduce a read barrier, as described in Note [Concurrent read barrier on deRefWeak#] (in `NonMovingMark.c`). * Stable names are also a bit tricky as described in Note [Sweeping stable names in the concurrent collector] (`NonMovingSweep.c`). We take quite some pains to ensure that the high thread count often seen in parallel Haskell applications doesn't affect pause times. To this end we allow thread stacks to be marked either by the thread itself (when it is executed or stack-underflows) or the concurrent mark thread (if the thread owning the stack is never scheduled). There is a non-trivial handshake to ensure that this happens without racing which is described in Note [StgStack dirtiness flags and concurrent marking]. Co-Authored-by: Ömer Sinan Ağacan <omer at well-typed.com> - - - - - dd1b4fdd by Ben Gamari at 2019-10-20T21:15:52-04:00 Nonmoving: Disable memory inventory with concurrent collection - - - - - 4a44ab33 by Ben Gamari at 2019-10-20T21:15:52-04:00 rts: Shrink size of STACK's dirty and marking fields - - - - - 10373416 by Ben Gamari at 2019-10-20T21:15:52-04:00 Don't cleanup until we've stopped the collector This requires that we break nonmovingExit into two pieces since we need to first stop the collector to relinquish any capabilities, then we need to shutdown the scheduler, then we need to free the nonmoving allocators. - - - - - 26c3827f by Ben Gamari at 2019-10-21T11:43:54-04:00 Nonmoving: Ensure write barrier vanishes in non-threaded RTS - - - - - 17e5a032 by Ben Gamari at 2019-10-21T11:43:54-04:00 ThreadPaused: Add barrer on updated thunk - - - - - 8ea316da by David Eichmann at 2019-10-22T02:07:48-04:00 CI: Always dump performance metrics. - - - - - aa31ceaf by Matthew Bauer at 2019-10-22T02:39:01-04:00 Replace freebsd-gnueabihf with freebsd FreeBSD does not support GNU libc, so it makes no sense to use this triple. Most likely previous builds were just using the FreeBSD libc instead of gnueabihf. To fix this, we should just use armv6-unknown-freebsd and armv7-unknown-freebsd triples. Note that both of these are actually "soft-float", not "hard-float". FreeBSD has never officially released hard-float arm32: https://wiki.freebsd.org/ARMTier1 - - - - - fd8b666a by Stefan Schulze Frielinghaus at 2019-10-22T02:39:03-04:00 Implement s390x LLVM backend. This patch adds support for the s390x architecture for the LLVM code generator. The patch includes a register mapping of STG registers onto s390x machine registers which enables a registerised build. - - - - - 2d2cc76f by Tilman Blumhagen at 2019-10-22T02:39:04-04:00 Documentation for (&&) and (&&) states that they are lazy in their second argument (fixes #17354) - - - - - 06d51c4e by Ben Gamari at 2019-10-22T12:13:36-04:00 Fix unregisterised build This required some fiddling around with the location of forward declarations since the C sources generated by GHC's C backend only includes Stg.h. - - - - - 912e440e by Ben Gamari at 2019-10-22T12:17:00-04:00 rts: Tracing support for nonmoving collection events This introduces a few events to mark key points in the nonmoving garbage collection cycle. These include: * `EVENT_CONC_MARK_BEGIN`, denoting the beginning of a round of marking. This may happen more than once in a single major collection since we the major collector iterates until it hits a fixed point. * `EVENT_CONC_MARK_END`, denoting the end of a round of marking. * `EVENT_CONC_SYNC_BEGIN`, denoting the beginning of the post-mark synchronization phase * `EVENT_CONC_UPD_REM_SET_FLUSH`, indicating that a capability has flushed its update remembered set. * `EVENT_CONC_SYNC_END`, denoting that all mutators have flushed their update remembered sets. * `EVENT_CONC_SWEEP_BEGIN`, denoting the beginning of the sweep portion of the major collection. * `EVENT_CONC_SWEEP_END`, denoting the end of the sweep portion of the major collection. - - - - - 9f42cd81 by Ben Gamari at 2019-10-22T12:17:00-04:00 rts: Introduce non-moving heap census This introduces a simple census of the non-moving heap (not to be confused with the heap census used by the heap profiler). This collects basic heap usage information (number of allocated and free blocks) which is useful when characterising fragmentation of the nonmoving heap. - - - - - 711837cc by Ben Gamari at 2019-10-22T12:17:00-04:00 rts/Eventlog: More descriptive error message - - - - - 0d31819e by Ben Gamari at 2019-10-22T12:17:00-04:00 Allow census without live word count Otherwise the census is unsafe when mutators are running due to concurrent mutation. - - - - - 6f173181 by Ben Gamari at 2019-10-22T12:17:00-04:00 NonmovingCensus: Emit samples to eventlog - - - - - 13dd78dd by Ben Gamari at 2019-10-22T12:18:33-04:00 Nonmoving: Allow aging and refactor static objects logic This commit does two things: * Allow aging of objects during the preparatory minor GC * Refactor handling of static objects to avoid the use of a hashtable - - - - - 7b79e8b4 by Ben Gamari at 2019-10-22T12:18:33-04:00 Disable aging when doing deadlock detection GC - - - - - 8fffe12b by Ben Gamari at 2019-10-22T12:18:33-04:00 More comments for aging - - - - - 039d2906 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Eliminate integer division in nonmovingBlockCount Perf showed that the this single div was capturing up to 10% of samples in nonmovingMark. However, the overwhelming majority of cases is looking at small block sizes. These cases we can easily compute explicitly, allowing the compiler to turn the division into a significantly more efficient division-by-constant. While the increase in source code looks scary, this all optimises down to very nice looking assembler. At this point the only remaining hotspots in nonmovingBlockCount are due to memory access. - - - - - d15ac82d by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Allocate mark queues in larger block groups - - - - - 26d2d331 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMovingMark: Optimize representation of mark queue This shortens MarkQueueEntry by 30% (one word) - - - - - e5eda61e by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Optimize bitmap search during allocation Use memchr instead of a open-coded loop. This is nearly twice as fast in a synthetic benchmark. - - - - - dacf4cae by Ben Gamari at 2019-10-22T12:18:39-04:00 rts: Add prefetch macros - - - - - 786c52d2 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Prefetch when clearing bitmaps Ensure that the bitmap of the segmentt that we will clear next is in cache by the time we reach it. - - - - - 0387df5b by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Inline nonmovingClearAllBitmaps - - - - - e893877e by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Fuse sweep preparation into mark prep - - - - - e6f6823f by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Pre-fetch during mark This improved overall runtime on nofib's constraints test by nearly 10%. - - - - - 56c5ebdc by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Prefetch segment header - - - - - 19bfe460 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Optimise allocator cache behavior Previously we would look at the segment header to determine the block size despite the fact that we already had the block size at hand. - - - - - 53a1a27e by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMovingMark: Eliminate redundant check_in_nonmoving_heaps - - - - - b967e470 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Don't do major GC if one is already running Previously we would perform a preparatory moving collection, resulting in many things being added to the mark queue. When we finished with this we would realize in nonmovingCollect that there was already a collection running, in which case we would simply not run the nonmoving collector. However, it was very easy to end up in a "treadmilling" situation: all subsequent GC following the first failed major GC would be scheduled as major GCs. Consequently we would continuously feed the concurrent collector with more mark queue entries and it would never finish. This patch aborts the major collection far earlier, meaning that we avoid adding nonmoving objects to the mark queue and allowing the concurrent collector to finish. - - - - - 3bc172a4 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Clean mut_list - - - - - 8e79e2a9 by Ben Gamari at 2019-10-22T12:18:39-04:00 Unconditionally flush update remembered set during minor GC Flush the update remembered set. The goal here is to flush periodically to ensure that we don't end up with a thread who marks their stack on their local update remembered set and doesn't flush until the nonmoving sync period as this would result in a large fraction of the heap being marked during the sync pause. - - - - - b281e80b by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Add nonmoving_thr way - - - - - 07987957 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Add nonmoving_thr_ghc way This uses the nonmoving collector when compiling the testcases. - - - - - 01fd0242 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Don't run T15892 in nonmoving ways The nonmoving GC doesn't support `+RTS -G1`, which this test insists on. - - - - - 097f4fd0 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Nonmoving collector doesn't support -G1 - - - - - 4b91dd25 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Ensure that threaded tests are run in nonmoving_thr - - - - - 78ce35b9 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: bug1010 requires -c, which isn't supported by nonmoving - - - - - 6e97cc47 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Skip T15892 in nonmoving_thr_ghc - - - - - 5ce853c8 by Ben Gamari at 2019-10-22T12:18:44-04:00 ghc-heap: Skip heap_all test with debugged RTS The debugged RTS initializes the heap with 0xaa, which breaks the (admittedly rather fragile) assumption that uninitialized fields are set to 0x00: ``` Wrong exit code for heap_all(nonmoving)(expected 0 , actual 1 ) Stderr ( heap_all ): heap_all: user error (assertClosuresEq: Closures do not match Expected: FunClosure {info = StgInfoTable {entry = Nothing, ptrs = 0, nptrs = 1, tipe = FUN_0_1, srtlen = 0, code = Nothing}, ptrArgs = [], dataArgs = [0]} Actual: FunClosure {info = StgInfoTable {entry = Nothing, ptrs = 0, nptrs = 1, tipe = FUN_0_1, srtlen = 1032832, code = Nothing}, ptrArgs = [], dataArgs = [12297829382473034410]} CallStack (from HasCallStack): assertClosuresEq, called at heap_all.hs:230:9 in main:Main ) ``` - - - - - 6abefce7 by Ben Gamari at 2019-10-22T12:18:44-04:00 Skip ghc_heap_all test in nonmoving ways - - - - - 99baff8c by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Don't run T9630 in nonmoving ways The nonmoving collector doesn't support -G1 - - - - - 25ae8f7d by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Don't run T7160 in nonmoving_thr ways The nonmoving way finalizes things in a different order. - - - - - 8cab149b by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Mark length001 as failing under nonmoving ways This is consistent with the other unoptimized ways. - - - - - 5b130b3d by Ben Gamari at 2019-10-22T12:18:46-04:00 Merge branches 'wip/gc/optimize' and 'wip/gc/test' into wip/gc/everything - - - - - 246ce2af by Ömer Sinan Ağacan at 2019-10-22T12:20:15-04:00 NonMoving: Implement indirection shortcutting This allows indirection chains residing in the non-moving heap to be shorted-out. - - - - - 875861ef by Ömer Sinan Ağacan at 2019-10-22T12:20:15-04:00 NonMoving: Implement selector optimisation - - - - - c72e84c6 by Ben Gamari at 2019-10-22T12:20:15-04:00 NonMovingMark: Handle INDs left by shortcutting - - - - - 0f8fd3c6 by Ömer Sinan Ağacan at 2019-10-22T12:20:15-04:00 NonMoving: Implement -xns to disable selector optimization - - - - - c936a245 by Ben Gamari at 2019-10-22T12:20:37-04:00 NonMoving: Introduce nonmovingSegmentLogBlockSize acccessor This will allow us to easily move the block size elsewhere. - - - - - 6dcef5ee by Ben Gamari at 2019-10-22T12:20:37-04:00 NonMoving: Move block size to block descriptor - - - - - dd8d1b49 by Ben Gamari at 2019-10-22T12:20:37-04:00 NonMoving: Move next_free_snap to block descriptor - - - - - 116e4646 by Ben Gamari at 2019-10-22T12:20:46-04:00 NonMoving: Add summarizing Note - - - - - 22eee2bc by Ben Gamari at 2019-10-22T12:20:48-04:00 Merge branches 'wip/gc/segment-header-to-bdescr' and 'wip/gc/docs' into wip/gc/everything2 - - - - - 3a862703 by Ömer Sinan Ağacan at 2019-10-22T18:56:32-04:00 rts: COMPACT_NFDATA support for the nonmoving collector This largely follows the model used for large objects, with appropriate adjustments made to account for references in the sharing deduplication hashtable. - - - - - 7c35d39b by Ben Gamari at 2019-10-22T18:56:32-04:00 rts: Mark nonmoving GC paths in moving collector as unlikely The expectation here is that the nonmoving GC is latency-centric, whereas the moving GC emphasizes throughput. Therefore we give the latter the benefit of better static branch prediction. - - - - - 91109404 by Ben Gamari at 2019-10-22T18:57:27-04:00 nonmoving: Trace GC preparation steps - - - - - a69b28f4 by Ben Gamari at 2019-10-22T18:57:27-04:00 nonmoving: Don't do two passes over large and compact object lists Previously we would first move the new objects to their appropriate non-moving GC list, then do another pass over that list to clear their mark bits. This is needlessly expensive. First clear the mark bits of the existing objects, then add the newly evacuated objects and, at the same time, clear their mark bits. This cuts the preparatory GC time in half for the Pusher benchmark with a large queue size. - - - - - 984745b0 by Ben Gamari at 2019-10-22T18:57:27-04:00 nonmoving: Upper-bound time we hold SM_MUTEX for during sweep - - - - - 96c5411a by David Feuer at 2019-10-23T05:58:37-04:00 Use an IORef for QSemN Replace the outer `MVar` in `QSemN` with an `IORef`. This should probably be lighter, and it removes the need for `uninterruptibleMask`. Previously Differential Revision https://phabricator.haskell.org/D4896 - - - - - faa30dcb by Andreas Klebinger at 2019-10-23T05:58:43-04:00 Warn about missing profiled libs when using the Interpreter. When GHC itself, or it's interpreter is profiled we need to load profiled libraries as well. This requirement is not always obvious, especially when TH implicilty uses the interpreter. When the libs were not found we fall back to assuming the are in a DLL. This is usually not the case so now we warn users when we do so. This makes it more obvious what is happening and gives users a way to fix the issue. This fixes #17121. - - - - - 1cd3fa29 by Richard Eisenberg at 2019-10-23T05:58:46-04:00 Implement a coverage checker for injectivity This fixes #16512. There are lots of parts of this patch: * The main payload is in FamInst. See Note [Coverage condition for injective type families] there for the overview. But it doesn't fix the bug. * We now bump the reduction depth every time we discharge a CFunEqCan. See Note [Flatten when discharging CFunEqCan] in TcInteract. * Exploration of this revealed a new, easy to maintain invariant for CTyEqCans. See Note [Almost function-free] in TcRnTypes. * We also realized that type inference for injectivity was a bit incomplete. This means we exchanged lookupFlattenTyVar for rewriteTyVar. See Note [rewriteTyVar] in TcFlatten. The new function is monadic while the previous one was pure, necessitating some faff in TcInteract. Nothing too bad. * zonkCt did not maintain invariants on CTyEqCan. It's not worth the bother doing so, so we just transmute CTyEqCans to CNonCanonicals. * The pure unifier was finding the fixpoint of the returned substitution, even when doing one-way matching (in tcUnifyTysWithTFs). Fixed now. Test cases: typecheck/should_fail/T16512{a,b} - - - - - 900cf195 by Alp Mestanogullari at 2019-10-23T05:58:48-04:00 compiler: introduce DynFlags plugins They have type '[CommandLineOpts] -> Maybe (DynFlags -> IO DynFlags)'. All plugins that supply a non-Nothing 'dynflagsPlugin' will see their updates applied to the current DynFlags right after the plugins are loaded. One use case for this is to superseede !1580 for registering hooks from a plugin. Frontend/parser plugins were considered to achieve this but they respectively conflict with how this plugin is going to be used and don't allow overriding/modifying the DynFlags, which is how hooks have to be registered. This commit comes with a test, 'test-hook-plugin', that registers a "fake" meta hook that replaces TH expressions with the 0 integer literal. - - - - - a19c7d17 by Ryan Scott at 2019-10-23T05:58:49-04:00 Reify oversaturated data family instances correctly (#17296) `TcSplice` was not properly handling oversaturated data family instances, such as the example in #17296, as it dropped arguments due to carelessly zipping data family instance arguments with `tyConTyVars`. For data families, the number of `tyConTyVars` can sometimes be less than the number of arguments it can accept in a data family instance due to the fact that data family instances can be oversaturated. To account for this, `TcSplice.mkIsPolyTvs` has now been renamed to `tyConArgsPolyKinded` and now factors in `tyConResKind` in addition to `tyConTyVars`. I've also added `Note [Reified instances and explicit kind signatures]` which explains the various subtleties in play here. Fixes #17296. - - - - - 9b2a5008 by Ben Gamari at 2019-10-23T05:58:50-04:00 testsuite: Don't run T7653 in ghci and profiled ways Currently this routinely fails in the i386 job. See #7653. - - - - - b521e8b6 by Ömer Sinan Ağacan at 2019-10-23T05:58:57-04:00 Refactor Compact.c: - Remove forward declarations - Introduce UNTAG_PTR and GET_PTR_TAG for dealing with pointer tags without having to cast arguments to StgClosure* - Remove dead code - Use W_ instead of StgWord - Use P_ instead of StgPtr - - - - - 17987a4b by Matthew Pickering at 2019-10-23T05:58:58-04:00 eventlog: Dump cost centre stack on each sample With this change it is possible to reconstruct the timing portion of a `.prof` file after the fact. By logging the stacks at each time point a more precise executation trace of the program can be observed rather than all identical cost centres being identified in the report. There are two new events: 1. `EVENT_PROF_BEGIN` - emitted at the start of profiling to communicate the tick interval 2. `EVENT_PROF_SAMPLE_COST_CENTRE` - emitted on each tick to communicate the current call stack. Fixes #17322 - - - - - 4798f3b9 by Takenobu Tani at 2019-10-23T05:59:00-04:00 Allow command name resolution for GHCi commands with option `!` #17345 This commit allows command name resolution for GHCi commands with option `!` as follows: ghci> :k! Int Int :: * = Int This commit changes implementation as follows: Before: * Prefix match with full string including the option `!` (e.g. `k!`) After (this patch): * Prefix match without option suffix `!` (e.g. `k`) * in addition, suffix match with option `!` See also #8305 and #8113 - - - - - aa778152 by Andreas Klebinger at 2019-10-23T05:59:01-04:00 Fix bug in the x86 backend involving the CFG. This is part two of fixing #17334. There are two parts to this commit: - A bugfix for computing loop levels - A bugfix of basic block invariants in the NCG. ----------------------------------------------------------- In the first bug we ended up with a CFG of the sort: [A -> B -> C] This was represented via maps as fromList [(A,B),(B,C)] and later transformed into a adjacency array. However the transformation did not include block C in the array (since we only looked at the keys of the map). This was still fine until we tried to look up successors for C and tried to read outside of the array bounds when accessing C. In order to prevent this in the future I refactored to code to include all nodes as keys in the map representation. And make this a invariant which is checked in a few places. Overall I expect this to make the code more robust as now any failed lookup will represent an error, versus failed lookups sometimes being expected and sometimes not. In terms of performance this makes some things cheaper (getting a list of all nodes) and others more expensive (adding a new edge). Overall this adds up to no noteable performance difference. ----------------------------------------------------------- Part 2: When the NCG generated a new basic block, it did not always insert a NEWBLOCK meta instruction in the stream which caused a quite subtle bug. During instruction selection a statement `s` in a block B with control of the sort: B -> C will sometimes result in control flow of the sort: ┌ < ┐ v ^ B -> B1 ┴ -> C as is the case for some atomic operations. Now to keep the CFG in sync when introducing B1 we clearly want to insert it between B and C. However there is a catch when we have to deal with self loops. We might start with code and a CFG of these forms: loop: stmt1 ┌ < ┐ .... v ^ stmtX loop ┘ stmtY .... goto loop: Now we introduce B1: ┌ ─ ─ ─ ─ ─┐ loop: │ ┌ < ┐ │ instrs v │ │ ^ .... loop ┴ B1 ┴ ┘ instrsFromX stmtY goto loop: This is simple, all outgoing edges from loop now simply start from B1 instead and the code generator knows which new edges it introduced for the self loop of B1. Disaster strikes if the statement Y follows the same pattern. If we apply the same rule that all outgoing edges change then we end up with: loop ─> B1 ─> B2 ┬─┐ │ │ └─<┤ │ │ └───<───┘ │ └───────<────────┘ This is problematic. The edge B1->B1 is modified as expected. However the modification is wrong! The assembly in this case looked like this: _loop: <instrs> _B1: ... cmpxchgq ... jne _B1 <instrs> <end _B1> _B2: ... cmpxchgq ... jne _B2 <instrs> jmp loop There is no edge _B2 -> _B1 here. It's still a self loop onto _B1. The problem here is that really B1 should be two basic blocks. Otherwise we have control flow in the *middle* of a basic block. A contradiction! So to account for this we add yet another basic block marker: _B: <instrs> _B1: ... cmpxchgq ... jne _B1 jmp _B1' _B1': <instrs> <end _B1> _B2: ... Now when inserting B2 we will only look at the outgoing edges of B1' and everything will work out nicely. You might also wonder why we don't insert jumps at the end of _B1'. There is no way another block ends up jumping to the labels _B1 or _B2 since they are essentially invisible to other blocks. View them as control flow labels local to the basic block if you'd like. Not doing this ultimately caused (part 2 of) #17334. - - - - - 1f40e68a by Ryan Yates at 2019-10-23T05:59:03-04:00 Full abort on validate failure merging `orElse`. Previously partial roll back of a branch of an `orElse` was attempted if validation failure was observed. Validation here, however, does not account for what part of the transaction observed inconsistent state. This commit fixes this by fully aborting and restarting the transaction. - - - - - 9c1f0f7c by Ben Gamari at 2019-10-23T05:59:03-04:00 Bump stm submodule - - - - - 6beea836 by Andreas Klebinger at 2019-10-23T05:59:04-04:00 Make dynflag argument for withTiming pure. 19 times out of 20 we already have dynflags in scope. We could just always use `return dflags`. But this is in fact not free. When looking at some STG code I noticed that we always allocate a closure for this expression in the heap. Clearly a waste in these cases. For the other cases we can either just modify the callsite to get dynflags or use the _D variants of withTiming I added which will use getDynFlags under the hood. - - - - - 8dd480cc by Matthew Pickering at 2019-10-23T05:59:06-04:00 Performance tests: Reduce acceptance threshold for bytes allocated tests The "new" performance testing infrastructure resets the baseline after every test so it's easy to miss gradual performance regressions over time. We should at least make these numbers smaller to catch patches which affect performance earlier. - - - - - 4af20bbc by Ben Gamari at 2019-10-23T05:59:06-04:00 users-guide: Fix :since: for -Wunused-packages Fixes #17382. - - - - - 21663693 by Ben Gamari at 2019-10-23T05:59:07-04:00 Drop duplicate -optl's from GHC invocations Previously the make build system would pass things like `-optl-optl-Wl,-x -optl-optl-Wl,noexecstack` to GHC. This would naturally result in mass confusion as GHC would pass `-optl-Wl,-x` to GCC. GCC would in turn interpret this as `-o ptl-Wl,-x`, setting the output pass of the invocation. The problem that `-optl` was added to the command-line in two places in the build system. Fix this. Fixes #17385. - - - - - bb0dc5a5 by Andreas Klebinger at 2019-10-23T05:59:07-04:00 Hadrian: Invoke ghc0 via bash when running tests to fix #17362. cmd uses RawCommand which uses Windows semantics to find the executable which sometimes seems to fail for unclear reasons. If we invoke ghc via bash then bash will find the ghc executable and the issue goes away. - - - - - 266435a7 by Ömer Sinan Ağacan at 2019-10-23T05:59:09-04:00 Add new flag for unarised STG dumps Previously -ddump-stg would dump pre and post-unarise STGs. Now we have a new flag for post-unarise STG and -ddump-stg only dumps coreToStg output. STG dump flags after this commit: - -ddump-stg: Dumps CoreToStg output - -ddump-stg-unarised: Unarise output - -ddump-stg-final: STG right before code gen (includes CSE and lambda lifting) - - - - - 8abddac8 by Ben Gamari at 2019-10-23T05:59:10-04:00 base: Add @since on GHC.IO.Handle.Lock.hUnlock Unfortunately this was introduced in base-4.11.0 (GHC 8.4.1) whereas the other locking primitives were added in base-4.10.0 (GHC 8.2.1). - - - - - 7f72b540 by Ben Gamari at 2019-10-23T14:56:46-04:00 Merge non-moving garbage collector This introduces a concurrent mark & sweep garbage collector to manage the old generation. The concurrent nature of this collector typically results in significantly reduced maximum and mean pause times in applications with large working sets. Due to the large and intricate nature of the change I have opted to preserve the fully-buildable history, including merge commits, which is described in the "Branch overview" section below. Collector design ================ The full design of the collector implemented here is described in detail in a technical note > B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell > Compiler" (2018) This document can be requested from @bgamari. The basic heap structure used in this design is heavily inspired by > K. Ueno & A. Ohori. "A fully concurrent garbage collector for > functional programs on multicore processors." /ACM SIGPLAN Notices/ > Vol. 51. No. 9 (presented at ICFP 2016) This design is intended to allow both marking and sweeping concurrent to execution of a multi-core mutator. Unlike the Ueno design, which requires no global synchronization pauses, the collector introduced here requires a stop-the-world pause at the beginning and end of the mark phase. To avoid heap fragmentation, the allocator consists of a number of fixed-size /sub-allocators/. Each of these sub-allocators allocators into its own set of /segments/, themselves allocated from the block allocator. Each segment is broken into a set of fixed-size allocation blocks (which back allocations) in addition to a bitmap (used to track the liveness of blocks) and some additional metadata (used also used to track liveness). This heap structure enables collection via mark-and-sweep, which can be performed concurrently via a snapshot-at-the-beginning scheme (although concurrent collection is not implemented in this patch). Implementation structure ======================== The majority of the collector is implemented in a handful of files: * `rts/Nonmoving.c` is the heart of the beast. It implements the entry-point to the nonmoving collector (`nonmoving_collect`), as well as the allocator (`nonmoving_allocate`) and a number of utilities for manipulating the heap. * `rts/NonmovingMark.c` implements the mark queue functionality, update remembered set, and mark loop. * `rts/NonmovingSweep.c` implements the sweep loop. * `rts/NonmovingScav.c` implements the logic necessary to scavenge the nonmoving heap. Branch overview =============== ``` * wip/gc/opt-pause: | A variety of small optimisations to further reduce pause times. | * wip/gc/compact-nfdata: | Introduce support for compact regions into the non-moving |\ collector | \ | \ | | * wip/gc/segment-header-to-bdescr: | | | Another optimization that we are considering, pushing | | | some segment metadata into the segment descriptor for | | | the sake of locality during mark | | | | * | wip/gc/shortcutting: | | | Support for indirection shortcutting and the selector optimization | | | in the non-moving heap. | | | * | | wip/gc/docs: | |/ Work on implementation documentation. | / |/ * wip/gc/everything: | A roll-up of everything below. |\ | \ | |\ | | \ | | * wip/gc/optimize: | | | A variety of optimizations, primarily to the mark loop. | | | Some of these are microoptimizations but a few are quite | | | significant. In particular, the prefetch patches have | | | produced a nontrivial improvement in mark performance. | | | | | * wip/gc/aging: | | | Enable support for aging in major collections. | | | | * | wip/gc/test: | | | Fix up the testsuite to more or less pass. | | | * | | wip/gc/instrumentation: | | | A variety of runtime instrumentation including statistics | | / support, the nonmoving census, and eventlog support. | |/ | / |/ * wip/gc/nonmoving-concurrent: | The concurrent write barriers. | * wip/gc/nonmoving-nonconcurrent: | The nonmoving collector without the write barriers necessary | for concurrent collection. | * wip/gc/preparation: | A merge of the various preparatory patches that aren't directly | implementing the GC. | | * GHC HEAD . . . ``` - - - - - 83655b06 by Ben Gamari at 2019-10-24T08:45:41-04:00 hadrian: Warn user if hadrian build fails due to lack of threaded RTS See #16873. - - - - - 6824f29a by Ryan Scott at 2019-10-24T08:46:19-04:00 Parenthesize GADT return types in pprIfaceConDecl (#17384) We were using `pprIfaceAppArgs` instead of `pprParendIfaceAppArgs` in `pprIfaceConDecl`. Oops. Fixes #17384. - - - - - 9de3f8b1 by Ryan Scott at 2019-10-24T18:38:32-04:00 Make isTcLevPoly more conservative with newtypes (#17360) `isTcLevPoly` gives an approximate answer for when a type constructor is levity polymorphic when fully applied, where `True` means "possibly levity polymorphic" and `False` means "definitely not levity polymorphic". `isTcLevPoly` returned `False` for newtypes, which is incorrect in the presence of `UnliftedNewtypes`, leading to #17360. This patch tweaks `isTcLevPoly` to return `True` for newtypes instead. Fixes #17360. - - - - - 243c72eb by Ryan Scott at 2019-10-24T18:39:08-04:00 Mark promoted InfixT names as IsPromoted (#17394) We applied a similar fix for `ConT` in #15572 but forgot to apply the fix to `InfixT` as well. This patch fixes #17394 by doing just that. - - - - - 87175e78 by James Foster at 2019-10-25T09:01:08-04:00 Make Hadrian use -dynamic-too in the basic case This commit makes Hadrian use the `-dynamic-too` flag when the current Flavour's libraryWays contains both vanilla and dynamic, cutting down the amount of repeated work caused by separate compilation of dynamic and static files. It does this for the basic case where '.o' and '.dyn_o' files are built with one command, but does not generalise to cases like '.prof_o' and '.prof_dyn_o'. - - - - - ecd89062 by Alp Mestanogullari at 2019-10-25T09:01:47-04:00 hadrian/ci: run testsuite against a freshly produced and installed bindist - - - - - 2a16b555 by Ben Gamari at 2019-10-25T09:02:26-04:00 testsuite: Mark T13786 as fragile in unreg build Due to #17018. - - - - - 08298926 by Ben Gamari at 2019-10-25T09:02:26-04:00 testsuite: Use fragile modifier in TH_foreignInterruptible It looks like this use of `skip` snuck through my previous refactoring. - - - - - 4c7d45d1 by Brian Wignall at 2019-10-25T09:03:04-04:00 Make documentation for byteSwap16 consistent with byteSwap32 (impl is same, with s/16/32) - - - - - 02822d84 by Ben Gamari at 2019-10-25T09:03:40-04:00 aclocal: A bit of reformatting - - - - - 519f5162 by Ben Gamari at 2019-10-25T09:03:40-04:00 configure: Drop GccLT46 GCC 4.6 was released 7 years ago. I think we can finally assume that it's available. This is a simplification prompted by #15742. - - - - - acedfc8b by Ben Gamari at 2019-10-25T09:04:16-04:00 gitlab-ci: Run check-uniques during lint job - - - - - 8916e64e by Andrew Martin at 2019-10-26T05:19:38-04:00 Implement shrinkSmallMutableArray# and resizeSmallMutableArray#. This is a part of GHC Proposal #25: "Offer more array resizing primitives". Resources related to the proposal: - Discussion: https://github.com/ghc-proposals/ghc-proposals/pull/121 - Proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0025-resize-boxed.rst Only shrinkSmallMutableArray# is implemented as a primop since a library-space implementation of resizeSmallMutableArray# (in GHC.Exts) is no less efficient than a primop would be. This may be replaced by a primop in the future if someone devises a strategy for growing arrays in-place. The library-space implementation always copies the array when growing it. This commit also tweaks the documentation of the deprecated sizeofMutableByteArray#, removing the mention of concurrency. That primop is unsound even in single-threaded applications. Additionally, the non-negativity assertion on the existing shrinkMutableByteArray# primop has been removed since this predicate is trivially always true. - - - - - 1be9c35c by Roland Senn at 2019-10-26T05:20:14-04:00 Fix #14690 - :steplocal panics after break-on-error `:steplocal` enables only breakpoints in the current top-level binding. When a normal breakpoint is hit, then the module name and the break id from the `BRK_FUN` byte code allow us to access the corresponding entry in a ModBreak table. From this entry we then get the SrcSpan (see compiler/main/InteractiveEval.hs:bindLocalsAtBreakpoint). With this source-span we can then determine the current top-level binding, needed for the steplocal command. However, if we break at an exception or at an error, we don't have an BRK_FUN byte-code, so we don't have any source information. The function `bindLocalsAtBreakpoint` creates an `UnhelpfulSpan`, which doesn't allow us to determine the current top-level binding. To avoid a `panic`, we have to check for `UnhelpfulSpan` in the function `ghc/GHCi/UI.hs:stepLocalCmd`. Hence a :steplocal command after a break-on-exception or a break-on-error is not possible. - - - - - 4820af10 by Adam Sandberg Eriksson at 2019-10-26T19:53:01-04:00 hadrian: point link to ghc gitlab [skip ci] - - - - - 609c7ee6 by Ben Gamari at 2019-10-26T19:53:36-04:00 gitlab-ci: Produce ARMv7 binary distributions - - - - - 8ac49411 by Ben Gamari at 2019-10-26T19:53:36-04:00 testsuite: Skip regalloc_unit_tests unless have_ncg This is a unit test for the native code generator's register allocator; naturally. the NCG is required. - - - - - 60575596 by Ben Gamari at 2019-10-26T19:53:36-04:00 Enable PDF documentation - - - - - 417f59d4 by Ben Gamari at 2019-10-26T19:53:36-04:00 rts: Fix ARM linker includes * Prefer #pragma once over guard macros * Drop redundant #includes * Fix order to ensure that necessary macros are defined when we condition on them - - - - - 4054f0e5 by Ömer Sinan Ağacan at 2019-10-26T19:54:16-04:00 Remove redundant -fno-cse options These were probably added with some GLOBAL_VARs, but those GLOBAL_VARs are now gone. - - - - - c62817f2 by Luke Lau at 2019-10-27T11:35:40-04:00 Fix RankNTypes :ghc-flag: in users guide This fixes a hadrian `build docs` failure - - - - - fc3a5205 by Luke Lau at 2019-10-27T11:35:40-04:00 Remove unused import - - - - - d2520bef by Luke Lau at 2019-10-27T11:35:40-04:00 Fix path to ghc-flags in users guide Hadrian rules It should point to the _build directory, not the source - - - - - 896d470a by Luke Lau at 2019-10-27T11:35:40-04:00 Add back documentation for deprecated -Whi-shadowing This was removed in b538476be3706264620c072e6e436debf9e0d3e4, but without it the compare-flags.py script fails. This adds it back and marks it as deprecated, with a notice that it is slated for removal. - - - - - 7d80f8b5 by Luke Lau at 2019-10-27T11:35:40-04:00 Remove documented flags from expected-undocumented-flags.txt - - - - - fa0d4809 by Ryan Scott at 2019-10-27T11:36:17-04:00 Parenthesize nullary constraint tuples using sigPrec (#17403) We were using `appPrec`, not `sigPrec`, as the precedence when determining whether or not to parenthesize `() :: Constraint`, which lead to the parentheses being omitted in function contexts like `(() :: Constraint) => String`. Easily fixed. Fixes #17403. - - - - - 90d06fd0 by Ben Gamari at 2019-10-27T17:27:17-04:00 hadrian: Silence output from Support SMP check Previously we would allow the output from the check of SMP support introduced by 83655b06e6d3e93b2d15bb0fa250fbb113d7fe68 leak to stdout. Silence this. See #16873. - - - - - 6635a3f6 by Josef Svenningsson at 2019-10-28T09:20:34-04:00 Fix #15344: use fail when desugaring applicative-do Applicative-do has a bug where it fails to use the monadic fail method when desugaring patternmatches which can fail. See #15344. This patch fixes that problem. It required more rewiring than I had expected. Applicative-do happens mostly in the renamer; that's where decisions about scheduling are made. This schedule is then carried through the typechecker and into the desugarer which performs the actual translation. Fixing this bug required sending information about the fail method from the renamer, through the type checker and into the desugarer. Previously, the desugarer didn't have enough information to actually desugar pattern matches correctly. As a side effect, we also fix #16628, where GHC wouldn't catch missing MonadFail instances with -XApplicativeDo. - - - - - cd9b9459 by Ryan Scott at 2019-10-28T09:21:13-04:00 Refactor TcDeriv to validity-check less in anyclass/via deriving (#13154) Due to the way `DerivEnv` is currently structured, there is an invariant that every derived instance must consist of a class applied to a non-empty list of argument types, where the last argument *must* be an application of a type constructor to some arguments. This works for many cases, but there are also some design patterns in standalone `anyclass`/`via` deriving that are made impossible due to enforcing this invariant, as documented in #13154. This fixes #13154 by refactoring `TcDeriv` and friends to perform fewer validity checks when using the `anyclass` or `via` strategies. The highlights are as followed: * Five fields of `DerivEnv` have been factored out into a new `DerivInstTys` data type. These fields only make sense for instances that satisfy the invariant mentioned above, so `DerivInstTys` is now only used in `stock` and `newtype` deriving, but not in other deriving strategies. * There is now a `Note [DerivEnv and DerivSpecMechanism]` describing the bullet point above in more detail, as well as explaining the exact requirements that each deriving strategy imposes. * I've refactored `mkEqnHelp`'s call graph to be slightly less complicated. Instead of the previous `mkDataTypeEqn`/`mkNewTypeEqn` dichotomy, there is now a single entrypoint `mk_eqn`. * Various bits of code were tweaked so as not to use fields that are specific to `DerivInstTys` so that they may be used by all deriving strategies, since not all deriving strategies use `DerivInstTys`. - - - - - e0e04856 by Alan Zimmerman at 2019-10-28T09:21:58-04:00 Attach API Annotations for {-# SOURCE #-} import pragma Attach the API annotations for the start and end locations of the {-# SOURCE #-} pragma in an ImportDecl. Closes #17388 - - - - - e951f219 by Sebastian Graf at 2019-10-28T09:22:35-04:00 Use FlexibleInstances for `Outputable (* p)` instead of match-all instances with equality constraints In #17304, Richard and Simon dicovered that using `-XFlexibleInstances` for `Outputable` instances of AST data types means users can provide orphan `Outputable` instances for passes other than `GhcPass`. Type inference doesn't currently to suffer, and Richard gave an example in #17304 that shows how rare a case would be where the slightly worse type inference would matter. So I went ahead with the refactoring, attempting to fix #17304. - - - - - ad1fe274 by Simon Peyton Jones at 2019-10-28T09:23:14-04:00 Better arity for join points A join point was getting too large an arity, leading to #17294. I've tightened up the invariant: see CoreSyn, Note [Invariants on join points], invariant 2b - - - - - fb4f245c by Takenobu Tani at 2019-10-29T03:45:02-04:00 users-guide: Fix :since: for -xn flag [skip ci] - - - - - 35abbfee by Takenobu Tani at 2019-10-29T03:45:41-04:00 users-guide: Add some new features and fix warnings for GHC 8.10 This updates the following: * Add description for ImportQualifiedPost extension * Add description for ghci command name resolution * Fix markdown warnings [skip ci] - - - - - 57dc1565 by Sylvain Henry at 2019-10-29T03:46:22-04:00 Use `not#` primitive to implement Word's complement - - - - - 28e52732 by Ben Gamari at 2019-10-29T03:46:59-04:00 linters: Add mode to lint given set of files This makes testing much easier. - - - - - db43b3b3 by Ben Gamari at 2019-10-29T03:46:59-04:00 linters: Add linter to catch unquoted use of $(TEST_HC) This is a common bug that creeps into Makefiles (e.g. see T12674). - - - - - ebee0d6b by Ben Gamari at 2019-10-29T03:46:59-04:00 testsuite: Fix quoting of $(TEST_HC) in T12674 I have no idea how this went unnoticed until now. - - - - - 3bd3456f by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 Refactor HscRecomp constructors: Make it evident in the constructors that the final interface is only available when HscStatus is not HscRecomp. (When HscStatus == HscRecomp we need to finish the compilation to get the final interface) `Maybe ModIface` return value of hscIncrementalCompile and the partial `expectIface` function are removed. - - - - - bbdd54aa by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 Return ModIface in compilation pipeline, remove IORef hack for generating ModIfaces The compilation phases now optionally return ModIface (for phases that generate an interface, currently only HscOut when (re)compiling a file). The value is then used by compileOne' to return the generated interface with HomeModInfo (which is then used by the batch mode compiler when building rest of the tree). hscIncrementalMode also returns a DynFlags with plugin info, to be used in the rest of the pipeline. Unfortunately this introduces a (perhaps less bad) hack in place of the previous IORef: we now record the DynFlags used to generate the partial infterface in HscRecomp and use the same DynFlags when generating the full interface. I spent almost three days trying to understand what's changing in DynFlags that causes a backpack test to fail, but I couldn't figure it out. There's a FIXME added next to the field so hopefully someone who understands this better than I do will fix it leter. - - - - - a56433a9 by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 Remove unused DynFlags arg of lookupIfaceByModule - - - - - dcd40c71 by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 HscMain: Move a comment closer to the relevant site - - - - - 593f6543 by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 MkIface: Remove redundant parameter and outdated comments from addFingerprints - - - - - f868e1fe by Ben Gamari at 2019-10-29T03:48:20-04:00 gitlab-ci: Use Hadrian for unregisterised job - - - - - 7b2ecbc0 by Ben Gamari at 2019-10-29T03:48:20-04:00 gitlab-ci: Factor out Linux Hadrian validation logic - - - - - 8e5de15d by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Define USE_LIBFFI_FOR_ADJUSTORS when necessary - - - - - 6a090270 by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Define NOSMP when building rts unregisterised It seems that NOSMP was previously only defined when compiling the compiler, not the RTS. Fix this. In addition do some spring-cleaning and make the logic match that of the Make build system. - - - - - b741d19d by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Shuffle around RTS build flags Some of these flags wanted to be passed to .cmm builds as well as C builds. - - - - - d7cedd9d by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Drop -Werror=unused-but-set-variable from GHC flags Previously `hadrian` would pass `-optc-Werror=unused-but-set-variable` to all GHC invocations. This was a difference from the make build system and cause the unregisterised build to fail as the C that GHC produces contains many unused functions. Drop it from the GHC flags. Note, however, that the flag is still present in `Settings.Builders.Common.cWarnings` and therefore will still be applied during compilation of C sources. - - - - - 7d3a15c7 by Ben Gamari at 2019-10-29T03:48:55-04:00 base: Fix open-file locking The OFD locking path introduced in 3b784d440d4b01b4c549df7c9a3ed2058edfc780 due to #13945 appears to have never actually worked but we never noticed due to an oversight in the autoconf check. Fix it. Thanks to Oleg Grenrus for noticing this. - - - - - 78b70e63 by Ben Gamari at 2019-10-29T03:48:55-04:00 base: Split up file locking implementation This makes the CPP significantly easier to follow. - - - - - 63977398 by Ben Gamari at 2019-10-29T03:49:31-04:00 Don't substitute GccVersion variable Not only is it now unused but we generally can't assume that we are compiling with GCC, so it really shouldn't be used. - - - - - 72f7ac9a by Ben Gamari at 2019-10-29T03:50:06-04:00 Revert "Replace freebsd-gnueabihf with freebsd" This reverts commit aa31ceaf7568802590f73a740ffbc8b800096342 as suggested in #17392. - - - - - 3c0372d6 by Ben Gamari at 2019-10-29T20:31:36-04:00 distrib: Fix binary distribution installation This had silently regressed due to 81860281 and the variable renaming performed in b55ee979, as noted in #17374. - - - - - a7f423ee by Ben Gamari at 2019-10-29T20:31:36-04:00 gitlab-ci: Use pxz to compress binary distributions - - - - - db602643 by Ben Gamari at 2019-10-29T20:31:36-04:00 Don't include settings file in binary distribution The configuration in the installation environment (as determined by `autoconf`) may differ from the build environment and therefore we need to be sure to rebuild the settings file. Fixes #17374. - - - - - 260e2379 by Ben Gamari at 2019-10-29T20:31:36-04:00 gitlab-ci: Fix binary distribution testing - - - - - 01ef3e1f by Ömer Sinan Ağacan at 2019-10-29T20:32:18-04:00 Interpreter: initialize arity fields of AP_NOUPDs AP_NOUPD entry code doesn't use the arity field, but not initializing this field confuses printers/debuggers, and also makes testing harder as the field's value changes randomly. - - - - - 93ff9197 by Ben Gamari at 2019-10-30T07:36:49-04:00 rts: More aarch64 header fixes - - - - - 3e7569bc by Vladislav Zavialov at 2019-10-30T07:36:50-04:00 Whitespace forward compatibility for proposal #229 GHC Proposal #229 changes the lexical rules of Haskell, which may require slight whitespace adjustments in certain cases. This patch changes formatting in a few places in GHC and its testsuite in a way that enables it to compile under the proposed rules. - - - - - 4898df1c by Ben Gamari at 2019-10-30T18:15:52-04:00 gitlab-ci: Fix the ARMv7 triple Previously we were configuring the ARMv7 builds with a host/target triple of arm-linux-gnueabihf, which caused us to target ARMv6 and consequently rely on the old CP15 memory barrier implementation. This barrier has to be emulated on ARMv8 machines which is glacially slow. Hopefully this should fix the ARMv7 builds which currently consistently time out. - - - - - 337e9b5a by Ömer Sinan Ağacan at 2019-10-31T19:01:54-04:00 Remove redundant 0s in ghc-heap pointer strings Before: 0x0000004200c86888 After: 0x42000224f8 This is more concise and consistent with the RTS's printer (which uses %p formatter, and at least on Linux gcc prints the short form) and gdb's pointer formatter. - - - - - 97b6f7a3 by Ben Gamari at 2019-10-31T19:02:32-04:00 base: Clamp IO operation size to 2GB on Darwin As reported in #17414, Darwin throws EINVAL in response to large writes. - - - - - a9743eb7 by Ben Gamari at 2019-10-31T19:02:32-04:00 testsuite: Add test for #17414 - - - - - 73d6e508 by Ben Gamari at 2019-10-31T19:03:10-04:00 base: Various haddock fixes Just a few things I found while looking at #17383. - - - - - dc487642 by taylorfausak at 2019-11-01T04:54:47-04:00 Implement `round` for `Ratio` that doesn't explode with `Natural`s - - - - - 3932fb97 by taylorfausak at 2019-11-01T04:54:47-04:00 Fix rounding around 0 - - - - - baf47ff8 by taylorfausak at 2019-11-01T04:54:47-04:00 Add tests for rounding ratios - - - - - 214d8122 by taylorfausak at 2019-11-01T04:54:47-04:00 Fix running of ratio test case - - - - - 70b62c97 by Ben Gamari at 2019-11-01T04:55:24-04:00 mmap: Factor out protection flags - - - - - c6759080 by Ben Gamari at 2019-11-01T04:55:24-04:00 rts: Make m32 allocator per-ObjectCode MacOS Catalina is finally going to force our hand in forbidden writable exeutable mappings. Unfortunately, this is quite incompatible with the current global m32 allocator, which mixes symbols from various objects in a single page. The problem here is that some of these symbols may not yet be resolved (e.g. had relocations performed) as this happens lazily (and therefore we can't yet make the section read-only and therefore executable). The easiest way around this is to simply create one m32 allocator per ObjectCode. This may slightly increase fragmentation for short-running programs but I suspect will actually improve fragmentation for programs doing lots of loading/unloading since we can always free all of the pages allocated to an object when it is unloaded (although this ability will only be implemented in a later patch). - - - - - 35c99e72 by Simon Peyton Jones at 2019-11-01T04:56:02-04:00 Makes Lint less chatty: I found in #17415 that Lint was printing out truly gigantic warnings, unmanageably huge, with repeated copies of the same thing. This patch makes Lint less chatty, especially for warnings: * For **warnings**, I don't print details of the location, unless you add `-dppr-debug`. * For **errors**, I still print all the info. They are fatal and stop exection, whereas warnings appear repeatedly. * I've made much less use of `AnExpr` in `LintLocInfo`; the expression can be gigantic. - - - - - d2471964 by Simon Peyton Jones at 2019-11-01T04:56:38-04:00 Add another test for #17267 This one came in a comment from James Payor - - - - - 1e2e82aa by Simon Peyton Jones at 2019-11-01T04:57:15-04:00 Fix a bad error in tcMatchTy This patch fixes #17395, a very subtle and hard-to-trigger bug in tcMatchTy. It's all explained in Note [Matching in the presence of casts (2)] I have not added a regression test because it is very hard to trigger it, until we have the upcoming mkAppTyM patch, after which lacking this patch means you can't even compile the libraries. - - - - - 51067194 by Ben Gamari at 2019-11-01T15:48:37-04:00 base: Ensure that failIO isn't SOURCE imported failIO has useful information in its demand signature (specifically that it bottoms) which is hidden if it is SOURCE imported, as noted in #16588. Rejigger things such that we don't SOURCE import it. Metric Increase: T13701 - - - - - c751082c by Ben Gamari at 2019-11-01T15:48:37-04:00 testsuite: Make ExplicitForAllRules1 more robust Previously the test relied on `id` not inlining. Fix this. - - - - - dab12c87 by Ben Gamari at 2019-11-01T15:48:37-04:00 Describe optimisation of demand analysis of noinline As described in #16588. - - - - - c9236384 by Adam Sandberg Eriksson at 2019-11-01T15:49:16-04:00 template-haskell: require at least 1 GADT constructor name (#17379) - - - - - a4ce26e0 by Ben Gamari at 2019-11-01T15:49:53-04:00 hadrian: Make runtest invocation consistency with Make Use True/False instead of 0/1. This shouldn't be a functional change but we should be consistent. - - - - - cabafe34 by Ben Gamari at 2019-11-01T15:50:29-04:00 testsuite: Add test for #17423 - - - - - 4a6d3d68 by Simon Peyton Jones at 2019-11-01T23:11:37-04:00 Make CSE delay inlining less CSE delays inlining a little bit, to avoid losing vital specialisations; see Note [Delay inlining after CSE] in CSE. But it was being over-enthusiastic. This patch makes the delay only apply to Ids with specialisation rules, which avoids unnecessary delay (#17409). - - - - - 01006bc7 by Niklas Hambüchen at 2019-11-01T23:12:17-04:00 doc: Fix backticks - - - - - 9980fb58 by Niklas Hambüchen at 2019-11-01T23:12:17-04:00 Add +RTS --disable-delayed-os-memory-return. Fixes #17411. Sets `MiscFlags.disableDelayedOsMemoryReturn`. See the added `Note [MADV_FREE and MADV_DONTNEED]` for details. - - - - - 182b1199 by Sebastian Graf at 2019-11-02T20:16:33-04:00 Separate `LPat` from `Pat` on the type-level Since the Trees That Grow effort started, we had `type LPat = Pat`. This is so that `SrcLoc`s would only be annotated in GHC's AST, which is the reason why all GHC passes use the extension constructor `XPat` to attach source locations. See #15495 for the design discussion behind that. But now suddenly there are `XPat`s everywhere! There are several functions which dont't cope with `XPat`s by either crashing (`hsPatType`) or simply returning incorrect results (`collectEvVarsPat`). This issue was raised in #17330. I also came up with a rather clean and type-safe solution to the problem: We define ```haskell type family XRec p (f :: * -> *) = r | r -> p f type instance XRec (GhcPass p) f = Located (f (GhcPass p)) type instance XRec TH f = f p type LPat p = XRec p Pat ``` This is a rather modular embedding of the old "ping-pong" style, while we only pay for the `Located` wrapper within GHC. No ping-ponging in a potential Template Haskell AST, for example. Yet, we miss no case where we should've handled a `SrcLoc`: `hsPatType` and `collectEvVarsPat` are not callable at an `LPat`. Also, this gets rid of one indirection in `Located` variants: Previously, we'd have to go through `XPat` and `Located` to get from `LPat` to the wrapped `Pat`. Now it's just `Located` again. Thus we fix #17330. - - - - - 3c916162 by Richard Eisenberg at 2019-11-02T20:17:13-04:00 Update Note references -- comments only Follow-on from !2041. - - - - - 3b65655c by Ben Gamari at 2019-11-04T03:40:31-05:00 SysTools: Only apply Windows-specific workaround on Windows Issue #1110 was apparently due to a bug in Vista which prevented GCC from finding its binaries unless we explicitly added it to PATH. However, this workaround was incorrectly applied on non-Windows platforms as well, resulting in ill-formed PATHs (#17266). Fixes #17266. - - - - - 5d4f16ee by Leif Metcalf at 2019-11-04T03:41:09-05:00 Rephrase note on full-laziness - - - - - 120f2e53 by Ben Gamari at 2019-11-04T03:41:44-05:00 rts/linker: Ensure that code isn't writable For many years the linker would simply map all of its memory with PROT_READ|PROT_WRITE|PROT_EXEC. However operating systems have been becoming increasingly reluctant to accept this practice (e.g. #17353 and #12657) and for good reason: writable code is ripe for exploitation. Consequently mmapForLinker now maps its memory with PROT_READ|PROT_WRITE. After the linker has finished filling/relocating the mapping it must then call mmapForLinkerMarkExecutable on the sections of the mapping which contain executable code. Moreover, to make all of this possible it was necessary to redesign the m32 allocator. First, we gave (in an earlier commit) each ObjectCode its own m32_allocator. This was necessary since code loading and symbol resolution/relocation are currently interleaved, meaning that it is not possible to enforce W^X when symbols from different objects reside in the same page. We then redesigned the m32 allocator to take advantage of the fact that all of the pages allocated with the allocator die at the same time (namely, when the owning ObjectCode is unloaded). This makes a number of things simpler (e.g. no more page reference counting; the interface provided by the allocator for freeing is simpler). See Note [M32 Allocator] for details. - - - - - 7c28087a by Takenobu Tani at 2019-11-05T02:45:31-05:00 users-guide: Improve documentaion of CPP extension Currently, the description of CPP extension is given in the section of command-line options. Therefore, it is a little difficult to understand that it is a language extension. This commit explicitly adds a description for it. [skip ci] - - - - - d57059f7 by Ben Gamari at 2019-11-05T02:46:10-05:00 rts: Add missing const in HEAP_ALLOCED_GC This was previously unnoticed as this code-path is hit on very few platforms (e.g. OpenBSD). - - - - - 487ede42 by Peter Trommler at 2019-11-05T02:46:48-05:00 testsuite: skip test requiring RTS linker on PowerPC The RTS linker is not available on 64-bit PowerPC. Instead of marking tests that require the RTS linker as broken on PowerPC 64-bit skip the respective tests on all platforms where the RTS linker or a statically linked external interpreter is not available. Fixes #11259 - - - - - 1593debf by Sebastian Graf at 2019-11-05T11:38:30-05:00 Check EmptyCase by simply adding a non-void constraint We can handle non-void constraints since !1733, so we can now express the strictness of `-XEmptyCase` just by adding a non-void constraint to the initial Uncovered set. For `case x of {}` we thus check that the Uncovered set `{ x | x /~ ⊥ }` is non-empty. This is conceptually simpler than the plan outlined in #17376, because it talks to the oracle directly. In order for this patch to pass the testsuite, I had to fix handling of newtypes in the pattern-match checker (#17248). Since we use a different code path (well, the main code path) for `-XEmptyCase` now, we apparently also handle #13717 correctly. There's also some dead code that we can get rid off now. `provideEvidence` has been updated to provide output more in line with the old logic, which used `inhabitationCandidates` under the hood. A consequence of the shift away from the `UncoveredPatterns` type is that we don't report reduced type families for empty case matches, because the pretty printer is pure and only knows the match variable's type. Fixes #13717, #17248, #17386 - - - - - e6ffe148 by Ömer Sinan Ağacan at 2019-11-05T11:39:13-05:00 TidyPgm: replace an explicit loop with mapAccumL - - - - - b7460492 by Ömer Sinan Ağacan at 2019-11-05T11:39:13-05:00 CoreTidy: hide tidyRule - - - - - f9978f53 by Stefan Schulze Frielinghaus at 2019-11-05T11:39:51-05:00 Hadrian: enable interpreter for s390x - - - - - 3ce18700 by Ben Gamari at 2019-11-06T08:05:57-05:00 rts: Drop redundant flags for libffi These are now handled in the cabal file's include-dirs field. - - - - - ce9e2a1a by Ben Gamari at 2019-11-06T08:05:57-05:00 configure: Add --with-libdw-{includes,libraries} flags Fixing #17255. - - - - - 97f9674b by Takenobu Tani at 2019-11-06T08:06:37-05:00 configure: Add checking python3-sphinx This checks the configuration about python3-sphinx. We need python3-sphinx instead of python2-sphinx to build documentation. The approach is as follows: * Check python3 version with custom `conf.py` invoked from sphinx-build` executable * Place custom `conf.py` into new `utils/check-sphinx` directory If sphinx is for python2 not python3, it's treated as config ERROR instead of WARN. See also #17346 and #17356. - - - - - b4fb2328 by Dan Brooks at 2019-11-06T08:07:15-05:00 Adding examples to Semigroup/monoid - - - - - 708c60aa by Ryan Scott at 2019-11-07T08:39:36-05:00 Clean up TH's treatment of unary tuples (or, #16881 part two) !1906 left some loose ends in regards to Template Haskell's treatment of unary tuples. This patch ends to tie up those loose ends: * In addition to having `TupleT 1` produce unary tuples, `TupE [exp]` and `TupP [pat]` also now produce unary tuples. * I have added various special cases in GHC's pretty-printers to ensure that explicit 1-tuples are printed using the `Unit` type. See `testsuite/tests/th/T17380`. * The GHC 8.10.1 release notes entry has been tidied up a little. Fixes #16881. Fixes #17371. Fixes #17380. - - - - - a424229d by Stefan Schulze Frielinghaus at 2019-11-07T08:40:13-05:00 For s390x issue a warning if LLVM 9 or older is used For s390x the GHC calling convention is only supported since LLVM version 10. Issue a warning in case an older version of LLVM is used. - - - - - 55bc3787 by Ben Gamari at 2019-11-07T08:40:50-05:00 FlagChecker: Add ticky flags to hashed flags These affect output and therefore should be part of the flag hash. - - - - - fa0b1b4b by Stefan Schulze Frielinghaus at 2019-11-07T08:41:33-05:00 Bump libffi-tarballs submodule - - - - - a9566632 by Takenobu Tani at 2019-11-07T08:42:15-05:00 configure: Modify ERROR to WARN for sphinx's python check If sphinx's python version check failed, many people prefer to build without documents instead of stopping on the error. So this commit fixes the following: * Modify AC_MSG_ERROR to AC_MSG_WARN * Add clearing of SPHINXBUILD variable when check fails See also !2016. - - - - - d0ef8312 by Alp Mestanogullari at 2019-11-07T21:24:59-05:00 hadrian: fix support for the recording of perf test results Before this patch, Hadrian didn't care about the TEST_ENV and METRICS_FILE environment variables, that the performance testing infrastructure uses to record perf tests results from CI jobs. It now looks them up right before running the testsuite driver, and passes suitable --test-env/--metrics-file arguments when these environment variables are set. - - - - - 601e554c by Ben Gamari at 2019-11-07T21:25:36-05:00 Bump the process submodule This should fix the #17108 and #17249 with the fix from https://github.com/haskell/process/pull/159. - - - - - 6b7d7e1c by Ben Gamari at 2019-11-07T21:25:36-05:00 Bump hsc2hs submodule - - - - - b1c158c9 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts: Fix m32 allocator build on Windows An inconsistency in the name of m32_allocator_flush caused the build to fail with a missing prototype error. - - - - - ae431cf4 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts: Ensure that Rts.h is always included first In general this is the convention that we use in the RTS. On Windows things actually fail if we break it. For instance, you see things like: includes\stg\Types.h:26:9: error: warning: #warning "Mismatch between __USE_MINGW_ANSI_STDIO definitions. If using Rts.h make sure it is the first header included." [-Wcpp] - - - - - 0d141d28 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts: Remove undesireable inline specifier I have no idea why I marked this as inline originally but clearly it shouldn't be inlined. - - - - - 870376f9 by Ben Gamari at 2019-11-07T21:25:36-05:00 base: Add missing imports in Windows locking implementation - - - - - 23994738 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts/NonMoving: Fix various Windows build issues The Windows build seems to be stricter about not providing threading primitives in the non-threaded RTS. - - - - - a3ce52fd by Ben Gamari at 2019-11-07T21:25:36-05:00 users_guide: Set flags list file encoding Otherwise this fails on Windows. - - - - - 9db2e905 by Stefan Schulze Frielinghaus at 2019-11-08T05:36:54-05:00 Testsuite: Introduce req_rts_linker Some tests depend on the RTS linker. Introduce a modifier to skip such tests, in case the RTS linker is not available. - - - - - a4631335 by Szymon Nowicki-Korgol at 2019-11-08T05:37:34-05:00 Set correct length of DWARF .debug_aranges section (fixes #17428) - - - - - 3db2ab30 by Ben Gamari at 2019-11-08T05:38:11-05:00 hadrian: Add enableTickyGhc helper This took a bit of trial-and-error to get working so it seems worth having in the tree. - - - - - 5c87ebd7 by Ben Gamari at 2019-11-08T12:09:22-05:00 SetLevels: Don't set context level when floating cases When floating a single-alternative case we previously would set the context level to the level where we were floating the case. However, this is wrong as we are only moving the case and its binders. This resulted in #16978, where the disrepancy caused us to unnecessarily abstract over some free variables of the case body, resulting in shadowing and consequently Core Lint failures. (cherry picked from commit a2a0e6f3bb2d02a9347dec4c7c4f6d4480bc2421) - - - - - 43623b09 by Ben Gamari at 2019-11-08T12:10:01-05:00 testsuite: Run tests in nonmoving_thr in speed==slow - - - - - 6e4656cc by Ben Gamari at 2019-11-08T12:10:01-05:00 rts/nonmoving: Catch failure of createOSThread - - - - - 2e4fc04b by Ben Gamari at 2019-11-08T12:10:01-05:00 Bump unix submodule Marks executeFile001 as broken in all concurrent ways. - - - - - 8a10f9fb by Ben Gamari at 2019-11-09T18:03:01-05:00 template-haskell: Document assembler foreign file support See #16180. - - - - - 5ad3cb53 by Ben Gamari at 2019-11-09T18:03:01-05:00 template-haskell: Fix TBAs in changelog - - - - - 4a75a832 by Ben Gamari at 2019-11-09T18:03:01-05:00 base: Fix TBA in changelog - - - - - d7de0d81 by Ryan Scott at 2019-11-09T18:03:02-05:00 template-haskell: Fix italics in changelog [ci-skip] - - - - - 0fb246c3 by Ben Gamari at 2019-11-09T18:03:37-05:00 testsuite: Fix Windows cleanup path This was a regression introduced with the Path refactoring. - - - - - 925fbdbb by Ben Gamari at 2019-11-09T18:03:37-05:00 testsuite: Skip T16916 on Windows The event manager is not supported on Windows. - - - - - 7c2ce0a0 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Skip T14931 on Windows This test uses -dynamic-too, which is not supported on Windows. - - - - - 7c63edb4 by Ben Gamari at 2019-11-09T18:03:38-05:00 gitlab-ci: Don't allow Windows make job to fail While linking is still slow (#16084) all of the correctness issues which were preventing us from being able to enforce testsuite-green on Windows are now resolved. - - - - - a50ecda6 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Fix header #include order on Windows <Rts.h> must always come first. - - - - - dcb23ec9 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T13676 as broken on Darwin and Windows Due to #17447. - - - - - 411ba7ba by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T11627b as fragile It was previously marked as broken due to #12236 however it passes for me locally while failing on CI. - - - - - c1f1f3f9 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T16219 as unbroken This was previously broken due to #16386 yet it passes for me locally. - - - - - 1f871e70 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Remove redundant cleaning logic from T16511 The GHCi script for T16511 had some `rm` commands to clean up output from previous runs. This should be harmless since stderr was redirected to /dev/null; however, it seems that this redirection doesn't work on Windows (perhaps because GHCi uses `cmd` to execute the command-line; I'm not sure). I tried to fix it but was unable to find a sensible solution. Regardless, the cleaning logic is quite redundant now that we run each test in a hermetic environment. Let's just remove it. - - - - - 4d523cb1 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T17414 as fragile on Windows This consistently times out on Windows as described in #17453. I have tried increasing the timeout multiplier to two yet it stills fails. Disabling until we have time to investigate. - - - - - f73fbd2d by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Ignore stderr in PartialDownsweep As described in #17449, PartialDownsweep is currently fragile due to its dependence on the error messages produced by the C preprocessor. To eliminate this dependence we simply ignore stderr output, instead relying on the fact that the test will exit with a non-zero exit code on failure. Fixes #17449. - - - - - a9b14790 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Fix putStrLn in saks028 Bizarrely, `saks028` previously failed reliably, but only on Windows (#17450). The test would exit with a zero exit code but simply didn't emit the expected text to stderr. I believe this was due to the fact that the test used `putStrLn`, resulting in the output ending up on stdout. This worked on other platforms since (apparently) we redirect stdout to stderr when evaluating splices. However, on Windows it seems that the redirected output wasn't flushed as it was on other platforms. Anyways, it seems like the right thing to do here is to be explicit about our desire for the output to end up on stderr. Closes #17450. - - - - - b62ca659 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Drop T7995 This test is quite sensitive to the build configuration as it requires that ghc have unfoldings, which isn't true in the quick build flavours. I considered various options to make the test more robust but none of them seemed particularly appealing. Moreover, Simon PJ was a bit skeptical of the value of the test to begin with and I strongly suspect that any regression in #7995 would be accompanied by failures in our other compiler performance tests. Closes #17399. - - - - - 011f3121 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T16219 as fragile on Windows As noted in #17452, this test produces very long file paths which exceed the Windows MAX_PATH limitation. Mark the test as fragile for not until we can come up with a better solution. - - - - - 1f98e47d by Simon Peyton Jones at 2019-11-09T18:04:14-05:00 Use the right type in :force A missing prime meant that we were considering the wrong type in the GHCi debugger, when doing :force on multiple arguments (issue #17431). The fix is trivial. - - - - - 1f911de4 by Brian Wignall at 2019-11-09T18:04:57-05:00 Add IsList instance for ZipList (closes #17433) - - - - - e3672f40 by Brian Wignall at 2019-11-09T18:04:57-05:00 Incorporate MR review suggestions; add change in changelog - - - - - 3957bdf2 by Brian Wignall at 2019-11-09T18:04:57-05:00 Fix incorrect plurals - - - - - 6f4c1250 by Alina Banerjee at 2019-11-10T01:06:12-05:00 Improve SPECIALIZE pragma error messages (Fixes #12126) - - - - - fa25c8c4 by Richard Eisenberg at 2019-11-10T01:06:48-05:00 Update release notes about #16512 / #17405. - - - - - 55ca1085 by Richard Eisenberg at 2019-11-10T01:06:48-05:00 Fix #17405 by not checking imported equations Previously, we checked all imported type family equations for injectivity. This is very silly. Now, we check only for conflicts. Before I could even imagine doing the fix, I needed to untangle several functions that were (in my opinion) overly complicated. It's still not quite as perfect as I'd like, but it's good enough for now. Test case: typecheck/should_compile/T17405 - - - - - a9467f4f by Ben Gamari at 2019-11-10T21:06:33-05:00 testsuite: Mark tests fragile in threaded2 as fragile in all concurrent ways - - - - - 3e07ea8d by Ben Gamari at 2019-11-10T21:10:30-05:00 testsuite: Use small allocation area when measuring residency As suggested in #17387; this helps reduce the variance in our residency sampling. Metric Increase: T10370 T3586 lazy-bs-alloc Metric Decrease 'compile_time/peak_megabytes_allocated': T1969 Metric Decrease 'runtime/bytes allocated': space_leak_001 Metric Increase 'compile_time/bytes allocated': T1969 Metric Increase 'runtime/peak_megabytes_allocated': space_leak_001 Metric Decrease: T3064 T9675 - - - - - 049d9ae0 by Ben Gamari at 2019-11-10T21:10:30-05:00 testsuite: Don't check_stats at runtime if not requested Previously we would call check_stats to check the runtime metrics even if the test definition hadn't requested it. This would result in an error since the .stats file doesn't exist. - - - - - 64433428 by Alp Mestanogullari at 2019-11-11T08:49:01-05:00 hadrian: export METRICS_FILE to make it accessible to perf notes script This addresses #17456 and also fixes the --metrics-file argument that Hadrian passes to the testsuite driver. - - - - - 06640394 by Ben Gamari at 2019-11-11T08:50:45-05:00 testsuite: Disable T4334 in nonmoving_thr way - - - - - f8ec32d7 by Alp Mestanogullari at 2019-11-11T11:36:44-05:00 ci: push perf test metrics even when the testsuite doesn't pass The corresponding commit might introduce a regression on a perf test, in which case we certainly want to record it. The testsuite might also fail because of a test unrelated to performance, in which case we want to record that the perf test results were good. Either way, we likely want to record them under all circumstances but we don't without this patch. Metric Decrease: T3586 Metric Increase: lazy-bs-alloc - - - - - 643d42fc by Alp Mestanogullari at 2019-11-12T18:40:19-05:00 testsuite: don't collect compiler stats in collect_runtime_residency We instead want to collect the runtime stats (with collect_stats, instead of collect_compiler_stats). This should fix a number of perf tests failures we have been seeing, where we suddenly started measuring metrics we didn't intend to measure, which tend to fall outside of the acceptance window. Metric Decrease: lazy-bs-alloc T3586 Metric Increase: space_leak_001 T4801 T5835 T12791 - - - - - 535d0edc by Ömer Sinan Ağacan at 2019-11-13T07:06:12-05:00 Document CmmTopInfo type [ci skip] - - - - - 2d4f9ad8 by Ben Gamari at 2019-11-13T07:06:49-05:00 Ensure that coreView/tcView are able to inline Previously an import cycle between Type and TyCoRep meant that several functions in TyCoRep ended up SOURCE import coreView. This is quite unfortunate as coreView is intended to be fused into a larger pattern match and not incur an extra call. Fix this with a bit of restructuring: * Move the functions in `TyCoRep` which depend upon things in `Type` into `Type` * Fold contents of `Kind` into `Type` and turn `Kind` into a simple wrapper re-exporting kind-ish things from `Type` * Clean up the redundant imports that popped up as a result Closes #17441. Metric Decrease: T4334 - - - - - b795637f by Alp Mestanogullari at 2019-11-13T07:07:28-05:00 hadrian: fix Windows CI script By only using 'export' from within bash commands. - - - - - 6885e22c by Ben Gamari at 2019-11-13T07:08:03-05:00 testsuite: Add test for #17458 As noted in #17458, QuantifiedConstraints and UndecideableInstances could previously be used to write programs which can loop at runtime. This was fixed in !1870. - - - - - b4b19d89 by Ben Gamari at 2019-11-13T07:08:03-05:00 users guide: Fix broken link - - - - - 9a939a6c by Ryan Scott at 2019-11-13T07:08:40-05:00 Print name prefixly in the Outputable instance for StandaloneKindSig Issue #17461 was occurring because the `Outputable` instance for standalone kind signatures was simply calling `ppr` on the name in the kind signature, which does not add parentheses to infix names. The solution is simple: use `pprPrefixOcc` instead. Fixes #17461. - - - - - a06cfb59 by Ömer Sinan Ağacan at 2019-11-13T07:09:18-05:00 Only pass mod_location with HscRecomp instead of the entire ModSummary HscRecomp users only need the ModLocation of the module being compiled, so only pass that to users instead of the entire ModSummary Metric Decrease: T4801 - - - - - dd49b3f0 by Ben Gamari at 2019-11-13T17:01:21-05:00 Bump Haskeline and add exceptions as boot library Haskeline now depends upon exceptions. See #16752. - - - - - b06b1858 by Ben Gamari at 2019-11-14T11:30:20-05:00 base: Bump version to 4.14.0.0 Metric Increase: T4801 - - - - - 6ab80439 by Ben Gamari at 2019-11-14T23:05:30-05:00 gitlab-ci: Allow Windows to fail again - - - - - 46afc380 by Ben Gamari at 2019-11-15T09:45:36-05:00 gitlab-ci: Install process to global pkgdb before starting build This is an attempt to mitigate #17480 by ensuring that a functional version of the process library is available before attempting the build. - - - - - 8c5cb806 by Ben Gamari at 2019-11-15T10:45:55-05:00 Bump supported LLVM version to 9.0 - - - - - 8e5851f0 by Ben Gamari at 2019-11-15T10:45:55-05:00 llvm-targets: Update with Clang 9 - - - - - f3ffec27 by Ben Gamari at 2019-11-15T11:54:26-05:00 testsuite: Increase acceptance window of T4801 This statistic is rather unstable. Hopefully fixes #17475. - - - - - c2991f16 by Ben Gamari at 2019-11-15T11:56:10-05:00 users-guide: Drop 8.6.1 release notes - - - - - e8da1354 by Ben Gamari at 2019-11-17T06:48:16-05:00 gitlab-ci: Fix submodule linter We ran it against the .git directory despite the fact that the linter wants to be run against the repository. - - - - - 13290f91 by Ben Gamari at 2019-11-17T06:48:16-05:00 Bump version to 8.10.0 Bumps haddock submodule. - - - - - fa98f823 by Ben Gamari at 2019-11-17T06:48:16-05:00 testsuite: Don't collect residency for T4801 I previously increased the size of the acceptance window from 2% to 5% but this still isn't enough. Regardless, measuring bytes allocated should be sufficient to catch any regressions. - - - - - 002b2842 by Ivan Kasatenko at 2019-11-17T06:49:22-05:00 Make test 16916 more stable across runs - - - - - ca89dd3b by Ben Gamari at 2019-11-17T06:58:17-05:00 users-guide: Address #17329 Adopts the language suggested by @JakobBruenker. - - - - - 2f5ed225 by Ben Gamari at 2019-11-17T07:16:32-05:00 exceptions: Bump submodule back to master The previous commit hasn't made it to master yet. - - - - - 34515e7c by nineonine at 2019-11-17T13:33:22-08:00 Fix random typos [skip ci] - - - - - 4a37a29b by Mario Blažević at 2019-11-17T17:26:24-05:00 Fixed issue #17435, missing Data instances - - - - - 97f1bcae by Andreas Klebinger at 2019-11-17T17:26:24-05:00 Turn some comments into GHC.Hs.Utils into haddocks - - - - - cf7f8e5b by Ben Gamari at 2019-11-17T17:26:26-05:00 testsuite: Skip T17414 on Linux It is typical for $TMP to be a small tmpfson Linux. This test will fail in such cases since we must create a file larger than the filesystem. See #17459. - - - - - 88013b78 by nineonine at 2019-11-19T11:53:16-05:00 Optimize MonadUnique instances based on IO (#16843) Metric Decrease: T14683 - - - - - a8adb5b4 by Ben Gamari at 2019-11-19T11:53:55-05:00 desugar: Drop stale Note [Matching seqId] The need for this note vanished in eae703aa60f41fd232be5478e196b661839ec3de. - - - - - 08d595c0 by Ben Gamari at 2019-11-19T11:53:55-05:00 Give seq a more precise type and remove magic `GHC.Prim.seq` previously had the rather plain type: seq :: forall a b. a -> b -> b However, it also had a special typing rule to applications where `b` is not of kind `Type`. Issue #17440 noted that levity polymorphism allows us to rather give it the more precise type: seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b This allows us to remove the special typing rule that we previously required to allow applications on unlifted arguments. T9404 contains a non-Type application of `seq` which should verify that this works as expected. Closes #17440. - - - - - ec8a463d by Viktor Dukhovni at 2019-11-19T11:54:45-05:00 Enable USE_PTHREAD_FOR_ITIMER also on FreeBSD If using a pthread instead of a timer signal is more reliable, and has no known drawbacks, then FreeBSD is also capable of supporting this mode of operation (tested on FreeBSD 12 with GHC 8.8.1, but no reason why it would not also work on FreeBSD 11 or GHC 8.6). Proposed by Kevin Zhang in: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=241849 - - - - - cd40e12a by Ömer Sinan Ağacan at 2019-11-19T11:55:36-05:00 Packages.hs: use O(n*log(n)) ordNub instead of O(n*n) nub As reported in #8173 in some environments package lists can get quite long, so we use more efficient ordNub instead of nub on package lists. - - - - - 2b27cc16 by Ben Gamari at 2019-11-19T11:56:21-05:00 Properly account for libdw paths in make build system Should finally fix #17255. - - - - - 0418c38d by Ben Gamari at 2019-11-19T11:56:58-05:00 rts: Add missing include of SymbolExtras.h This broke the Windows build. - - - - - c819c0e4 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Use correct info table pointer accessor Previously we used INFO_PTR_TO_STRUCT instead of THUNK_INFO_PTR_TO_STRUCT when looking at a thunk. These two happen to be equivalent on 64-bit architectures due to alignment considerations however they are different on 32-bit platforms. This lead to #17487. To fix this we also employ a small optimization: there is only one thunk of type WHITEHOLE (namely stg_WHITEHOLE_info). Consequently, we can just use a plain pointer comparison instead of testing against info->type. - - - - - deed8e31 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Fix incorrect masking in mark queue type test We were using TAG_BITS instead of TAG_MASK. This happened to work on 64-bit platforms where TAG_BITS==3 since we only use tag values 0 and 3. However, this broken on 32-bit platforms where TAG_BITS==2. - - - - - 097f8072 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Rework mark queue representation The previous representation needlessly limited the array length to 16-bits on 32-bit platforms. - - - - - eb7b233a by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Fix handling on large object marking on 32-bit Previously we would reset the pointer pointing to the object to be marked to the beginning of the block when marking a large object. This did no harm on 64-bit but on 32-bit it broke, e.g. `arr020`, since we align pinned ByteArray allocations such that the payload is 8 byte-aligned. This means that the object might not begin at the beginning of the block., - - - - - a7571a74 by Ben Gamari at 2019-11-19T11:57:36-05:00 testsuite: Increase width of stack003 test Previously the returned tuple seemed to fit in registers on amd64. This meant that non-moving collector bug would cause the test to fail on i386 yet not amd64. - - - - - 098d5017 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Drop redundant write barrier on stack underflow Previously we would push stack-carried return values to the new stack on a stack overflow. While the precise reasoning for this barrier is unfortunately lost to history, in hindsight I suspect it was prompted by a missing barrier elsewhere (that has been since fixed). Moreover, there the redundant barrier is actively harmful: the stack may contain non-pointer values; blindly pushing these to the mark queue will result in a crash. This is precisely what happened in the `stack003` test. However, because of a (now fixed) deficiency in the test this crash did not trigger on amd64. - - - - - e57b7cc6 by Roland Zumkeller at 2019-11-19T20:39:19-05:00 Changing Thread IDs from 32 bits to 64 bits. - - - - - d1f3c637 by Roland Zumkeller at 2019-11-19T20:39:19-05:00 Use pointer equality in Eq/Ord for ThreadId Changes (==) to use only pointer equality. This is safe because two threads are the same iff they have the same id. Changes `compare` to check pointer equality first and fall back on ids only in case of inequality. See discussion in #16761. - - - - - ef8a08e0 by Alexey Kuleshevich at 2019-11-19T20:39:20-05:00 hpc: Fix encoding issues. Add test for and fix #17073 * Make sure files are being read/written in UTF-8. Set encoding while writing HTML output. Also set encoding while writing and reading .tix files although we don't yet have a ticket complaining that this poses problems. * Set encoding in html header to utf8 * Upgrade to new version of 'hpc' library and reuse `readFileUtf8` and `writeFileUtf8` functions * Update git submodule for `hpc` * Bump up `hpc` executable version Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - b79e46d6 by Vladislav Zavialov at 2019-11-19T20:39:20-05:00 Strip parentheses in expressions contexts in error messages This makes error messages a tad less noisy. - - - - - 13bbde77 by Ben Gamari at 2019-11-21T13:56:56-05:00 Bump hsc2hs submodule Including Phyx's backport of the process changes fixing #17480. - - - - - d4d10501 by Ben Gamari at 2019-11-23T09:42:38-05:00 Bump hsc2hs submodule again This fixes the Darwin build. - - - - - 889d475b by nineonine at 2019-11-23T18:53:29-05:00 Fix typo in Note reference [skip ci] - - - - - 8a33abfc by Ryan Scott at 2019-11-23T18:54:05-05:00 Target the IsList instance for ZipList at base-4.14.0.0 (#17489) This moves the changelog entry about the instance from `base-4.15.0.0` to `base-4.14.0.0`. This accomplishes part (1) from #17489. [ci skip] - - - - - e43e6ece by Ben Gamari at 2019-11-23T18:54:41-05:00 rts: Expose interface for configuring EventLogWriters This exposes a set of interfaces from the GHC API for configuring EventLogWriters. These can be used by consumers like [ghc-eventlog-socket](https://github.com/bgamari/ghc-eventlog-socket). - - - - - de6bbdf2 by Matheus Magalhães de Alcantara at 2019-11-23T18:55:23-05:00 Take care to not eta-reduce jumps in CorePrep CorePrep already had a check to prevent it from eta-reducing Ids that respond true to hasNoBinding (foreign calls, constructors for unboxed sums and products, and Ids with compulsory unfoldings). It did not, however, consider join points as ids that 'must be saturated'. Checking whether the Id responds True to 'isJoinId' should prevent CorePrep from turning saturated jumps like the following (from #17429) into undersaturated ones: (\ eta_XP -> join { mapped_s1vo _ = lvl_s1vs } in jump mapped_s1vo eta_XP) - - - - - 4a1e7e47 by Matheus Magalhães de Alcantara at 2019-11-23T18:55:23-05:00 Make CorePrep.tryEtaReducePrep and CoreUtils.tryEtaReduce line up Simon PJ says he prefers this fix to #17429 over banning eta-reduction for jumps entirely. Sure enough, this also works. Test case: simplCore/should_compile/T17429.hs - - - - - 15f1dc33 by Ryan Scott at 2019-11-23T18:56:00-05:00 Prevent -optc arguments from being duplicated in reverse order (#17471) This reverts a part of commit 7bc5d6c6578ab9d60a83b81c7cc14819afef32ba that causes all arguments to `-optc` (and `-optcxx`) to be passed twice to the C/C++ compiler, once in reverse order and then again in the correct order. While passing duplicate arguments is usually harmless it can cause breakage in this pattern, which is employed by Hackage libraries in the wild: ``` ghc Foo.hs foo.c -optc-D -optcFOO ``` As `FOO -D -D FOO` will cause compilers to error. Fixes #17471. - - - - - e85c9b22 by Ben Gamari at 2019-11-23T18:56:36-05:00 Bump ghc version to 8.11 - - - - - 0e6c2045 by Ben Gamari at 2019-11-23T18:57:12-05:00 rts: Consolidate spinlock implementation Previously we had two distinct implementations: one with spinlock profiling and another without. This seems like needless duplication. - - - - - cb11fcb5 by Ben Gamari at 2019-11-23T18:57:49-05:00 Packages: Don't use expectJust Throw a slightly more informative error on failure. Motivated by the errors seen in !2160. - - - - - 5747ebe9 by Sebastian Graf at 2019-11-23T18:58:25-05:00 Stricten functions ins GHC.Natural This brings `Natural` on par with `Integer` and fixes #17499. Also does some manual CSE for 0 and 1 literals. - - - - - c14b723f by Ömer Sinan Ağacan at 2019-11-23T18:59:06-05:00 Bump exceptions submodule Adds a few files generated by GHC's configure script to .gitignore - - - - - 7b4c7b75 by Brian Wignall at 2019-11-23T19:04:52-05:00 Fix typos - - - - - 6008206a by Viktor Dukhovni at 2019-11-24T14:33:18-05:00 On FreeBSD 12 sys/sysctl.h requires sys/types.h Else build fails with: In file included from ExecutablePath.hsc:42: /usr/include/sys/sysctl.h:1062:25: error: unknown type name 'u_int'; did you mean 'int'? int sysctl(const int *, u_int, void *, size_t *, const void *, size_t); ^~~~~ int compiling libraries/base/dist-install/build/System/Environment/ExecutablePath_hsc_make.c failed (exit code 1) Perhaps also also other FreeBSD releases, but additional include will no harm even if not needed. - - - - - b694b566 by Ben Gamari at 2019-11-24T14:33:54-05:00 configure: Fix HAVE_C11_ATOMICS macro Previously we were using AC_DEFINE instead of AC_DEFINE_UNQUOTED, resulted in the variable not being interpolated. Fixes #17505. - - - - - 8b8dc366 by Krzysztof Gogolewski at 2019-11-25T14:37:38+01:00 Remove prefix arrow support for GADTs (#17211) This reverts the change in #9096. The specialcasing done for prefix (->) is brittle and does not support VTA, type families, type synonyms etc. - - - - - 5a08f7d4 by Sebastian Graf at 2019-11-27T00:14:59-05:00 Make warnings for TH splices opt-in In #17270 we have the pattern-match checker emit incorrect warnings. The reason for that behavior is ultimately an inconsistency in whether we treat TH splices as written by the user (`FromSource :: Origin`) or as generated code (`Generated`). This was first reported in #14838. The current solution is to TH splices as `Generated` by default and only treat them as `FromSource` when the user requests so (-fenable-th-splice-warnings). There are multiple reasons for opt-in rather than opt-out: * It's not clear that the user that compiles a splice is the author of the code that produces the warning. Think of the situation where she just splices in code from a third-party library that produces incomplete pattern matches. In this scenario, the user isn't even able to fix that warning. * Gathering information for producing the warnings (pattern-match check warnings in particular) is costly. There's no point in doing so if the user is not interested in those warnings. Fixes #17270, but not #14838, because the proper solution needs a GHC proposal extending the TH AST syntax. - - - - - 8168b42a by Vladislav Zavialov at 2019-11-27T11:32:18+03:00 Whitespace-sensitive bang patterns (#1087, #17162) This patch implements a part of GHC Proposal #229 that covers five operators: * the bang operator (!) * the tilde operator (~) * the at operator (@) * the dollar operator ($) * the double dollar operator ($$) Based on surrounding whitespace, these operators are disambiguated into bang patterns, lazy patterns, strictness annotations, type applications, splices, and typed splices. This patch doesn't cover the (-) operator or the -Woperator-whitespace warning, which are left as future work. - - - - - 9e5477c4 by Ryan Scott at 2019-11-27T20:01:50-05:00 Fix @since annotations for isResourceVanishedError and friends (#17488) - - - - - e122ba33 by Sergei Trofimovich at 2019-11-27T20:02:29-05:00 .gitmodules: tweak 'exception' URL to avoid redirection warnings Avoid initial close warning of form: ``` Cloning into 'exceptions'... warning: redirecting to https://gitlab.haskell.org/ghc/packages/exceptions.git/ ``` Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f84b52a by Philipp Krüger at 2019-11-28T02:54:05-05:00 Reduce boolean blindness in OccInfo(OneOcc) #17482 * Transformed the type aliases `InterestingCxt`, `InsideLam` and `OneBranch` into data types. * Added Semigroup and Monoid instances for use in orOccInfo in OccurAnal.hs * Simplified some usage sites by using pattern matching instead of boolean algebra. Metric Increase: T12150 This increase was on a Mac-build of exactly 1%. This commit does *not* re-intruduce the asymptotic memory usage described in T12150. - - - - - 3748ba3a by Brian Wignall at 2019-11-28T02:54:52-05:00 Fix typos, using Wikipedia list of common typos - - - - - 6c59cc71 by Stefan Schulze Frielinghaus at 2019-11-28T02:55:33-05:00 Fix endian handling of LLVM backend Get rid of CPP macro WORDS_BIGENDIAN which is not defined anymore, and replace it by DynFlag. This fixes partially #17337. - - - - - 6985e0fc by Vladislav Zavialov at 2019-11-28T15:47:53+03:00 Factor out HsSCC/HsCoreAnn/HsTickPragma into HsPragE This is a refactoring with no user-visible changes (except for GHC API users). Consider the HsExpr constructors that correspond to user-written pragmas: HsSCC representing {-# SCC ... #-} HsCoreAnn representing {-# CORE ... #-} HsTickPragma representing {-# GENERATED ... #-} We can factor them out into a separate datatype, HsPragE. It makes the code a bit tidier, especially in the parser. Before this patch: hpc_annot :: { Located ( (([AddAnn],SourceText),(StringLiteral,(Int,Int),(Int,Int))), ((SourceText,SourceText),(SourceText,SourceText)) ) } After this patch: prag_hpc :: { Located ([AddAnn], HsPragE GhcPs) } - - - - - 7f695a20 by Ömer Sinan Ağacan at 2019-11-29T08:25:28-05:00 Pass ModDetails with (partial) ModIface in HscStatus (Partial) ModIface and ModDetails are generated at the same time, but they're passed differently: ModIface is passed in HscStatus consturctors while ModDetails is returned in a tuple. This refactors ModDetails passing so that it's passed around with ModIface in HscStatus constructors. This makes the code more consistent and hopefully easier to understand: ModIface and ModDetails are really very closely related. It makes sense to treat them the same way. - - - - - e921c90f by Ömer Sinan Ağacan at 2019-11-29T08:26:07-05:00 Improve few Foreign.Marshal.Utils docs In copyBytes and moveBytes mention which argument is source and which is destination. Also fixes some of the crazy indentation in the module and cleans trailing whitespace. - - - - - 316f2431 by Sebastian Graf at 2019-11-30T02:57:58-05:00 Hadrian docs: Rename the second "validate" entry to "slow-validate" [ci skip] That would be in line with the implementation. - - - - - 5aba5d32 by Vladislav Zavialov at 2019-11-30T02:58:34-05:00 Remove HasSrcSpan (#17494) Metric Decrease: haddock.compiler - - - - - d1de5c22 by Sylvain Henry at 2019-11-30T02:59:13-05:00 Use Hadrian by default in validate script (#17527) - - - - - 3a96a0b6 by Sebastian Graf at 2019-11-30T02:59:55-05:00 Simpler Semigroup instance for InsideLam and InterestingCtxt This mirrors the definition of `(&&)` and `(||)` now, relieving the Simplifier of a marginal amount of pressure. - - - - - f8cfe81a by Roland Senn at 2019-11-30T20:33:49+01:00 Improve tests for #17171 While backporting MR !1806 to 8.8.2 (!1885) I learnt the following: * Tests with `expect_fail` do not compare `*.stderr` output files. So a test using `expect_fail` will not detect future regressions on the `stderr` output. * To compare the `*.stderr` output files, I have to use the `exit_code(n)` function. * When a release is made, tests with `makefile_test` are converted to use `run_command`. * For the test `T17171a` the return code is `1` when running `makefile_test`, however it's `2` when running `run_command`. Therefore I decided: * To improve my tests for #17171 * To change test T17171a from `expect_fail` to `exit_code(2)` * To change both tests from `makefile_test` to `run_command` - - - - - 2b113fc9 by Vladislav Zavialov at 2019-12-01T08:17:05-05:00 Update DisambECP-related comments - - - - - beed7c3e by Ben Gamari at 2019-12-02T03:41:37-05:00 testsuite: Fix location of typing_stubs module This should fix the build on Debian 8. - - - - - 53251413 by Ben Gamari at 2019-12-02T03:42:14-05:00 testsuite: Don't override LD_LIBRARY_PATH, only prepend NixOS development environments often require that LD_LIBRARY_PATH be set in order to find system libraries. T1407 was overriding LD_LIBRARY_PATH, dropping these directories. Now it merely prepends, its directory. - - - - - 65400314 by Krzysztof Gogolewski at 2019-12-02T03:42:57-05:00 Convert warnings into assertions Since the invariants always hold in the testsuite, we can convert them to asserts. - - - - - 18baed64 by Alan Zimmerman at 2019-12-02T03:43:37-05:00 API Annotations: Unicode '->' on HsForallTy The code fragment type family Proxy2' ∷ ∀ k → k → Type where Proxy2' = Proxy' Generates AnnRarrow instead of AnnRarrowU for the first →. Fixes #17519 - - - - - 717f3236 by Brian Wignall at 2019-12-02T03:44:16-05:00 Fix more typos - - - - - bde48f8e by Ben Gamari at 2019-12-02T11:55:34-05:00 More Haddock syntax in GHC.Hs.Utils As suggested by RyanGlScott in !2163. - - - - - 038bedbc by Ben Gamari at 2019-12-02T11:56:18-05:00 Simplify: Fix pretty-printing of strictness A colleague recently hit the panic in Simplify.addEvals and I noticed that the message is quite unreadable due to incorrect pretty-printing. Fix this. - - - - - c500f652 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix changelog linting logic - - - - - 8ead967d by Ben Gamari at 2019-12-02T11:56:54-05:00 win32-init: Drop workaround for #17480 The `process` changes have now been merged into `hsc2hs`. (cherry picked from commit fa029f53132ad59f847ed012d3b835452cf16615) - - - - - d402209a by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Disable Sphinx build on Debian 8 The docutils version available appears to be too old to support the `table` directive's `:widths:` options. (cherry picked from commit 75764487a96a7a026948b5af5022781872d12baa) - - - - - f1f68824 by Ben Gamari at 2019-12-02T11:56:54-05:00 base: Fix <unistd.h> #include Previously we were including <sys/unistd.h> which is available on glibc but not musl. (cherry picked from commit e44b695ca7cb5f3f99eecfba05c9672c6a22205e) - - - - - 37eb94b3 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Bump Docker images Installs pxz on Centos7 (cherry picked from commit 86960e691f7a600be247c32a7cf795bf9abf7cc4) - - - - - aec98a79 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: pxz is unavailable on CentOS 7 Fall back to xz - - - - - 6708b8e5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Set LANG on CentOS 7 It otherwise seems to default to ascii - - - - - 470ef0e7 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Consolidate release build configuration - - - - - 38338757 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add Debian 10 builds - - - - - 012f13b5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix Windows bindist collection Apparently variable interpolation in the `artifacts.paths` key of `gitlab-ci.yml` doesn't work on Windows as it does on WIndows. (cherry picked from commit 100cc756faa4468ed6950116bae30609c1c3468b) - - - - - a0f09e23 by Ben Gamari at 2019-12-02T11:56:54-05:00 testsuite: Simplify Python <3.5 fallback for TextIO (cherry picked from commit d092d8598694c23bc07cdcc504dff52fa5f33be1) - - - - - 2b2370ec by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add release-x86_64-linux-deb9 job (cherry picked from commit cbedb3c4a90649f474cb716842ba53afc5a642ca) - - - - - b1c206fd by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Always build source tarball (cherry picked from commit 67b5de88ef923971f1980335137e3c7193213abd) - - - - - 4cbd5b47 by Sergei Trofimovich at 2019-12-02T11:57:33-05:00 configure.ac: make cross-compiler detection stricter Be more precise at detecting cross-compilation case. Before the change configuration $ ./configure --host=x86_64-pc-linux-gnu --target=x86_64-gentoo-linux-musl was not considered a cross-target. Even though libcs are different (`glibc` vs. `musl`). Without this patch build fails as: ``` "inplace/bin/ghc-cabal" check libraries/integer-gmp "inplace/bin/ghc-cabal" configure libraries/integer-gmp dist-install \ --with-ghc="/home/slyfox/dev/git/ghc/inplace/bin/ghc-stage1" \ --with-ghc-pkg="/home/slyfox/dev/git/ghc/inplace/bin/ghc-pkg" \ --disable-library-for-ghci --enable-library-vanilla --enable-library-for-ghci \ --enable-library-profiling --enable-shared --with-hscolour="/usr/bin/HsColour" \ --configure-option=CFLAGS="-Wall \ -Werror=unused-but-set-variable -Wno-error=inline \ -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp" \ --configure-option=LDFLAGS=" " --configure-option=CPPFLAGS=" \ " --gcc-options="-Wall -Werror=unused-but-set-variable -Wno-error=inline -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp \ " --with-gcc="x86_64-gentoo-linux-musl-gcc" --with-ld="x86_64-gentoo-linux-musl-ld.gold" --with-ar="x86_64-gentoo-linux-musl-ar" \ --with-alex="/usr/bin/alex" --with-happy="/usr/bin/happy" Configuring integer-gmp-1.0.2.0... configure: WARNING: unrecognized options: --with-compiler checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking target system type... x86_64-pc-linux-gnu checking for gcc... /usr/lib/ccache/bin/x86_64-gentoo-linux-musl-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... configure: error: in `/home/slyfox/dev/git/ghc/libraries/integer-gmp/dist-install/build': configure: error: cannot run C compiled programs. If you meant to cross compile, use `--host'. See `config.log' for more details make[1]: *** [libraries/integer-gmp/ghc.mk:5: libraries/integer-gmp/dist-install/package-data.mk] Error 1 make: *** [Makefile:126: all] Error 2 ``` Note: here `ghc-stage1` is assumed to target `musl` target but is passed `glibc` toolchain. It happens because initial ./configure phase did not detect host/target as different. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f7cb423 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Add `timesInt2#` primop - - - - - fbbe18a2 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Use the new timesInt2# primop in integer-gmp (#9431) - - - - - 5a4b8d0c by Athas at 2019-12-03T00:00:09-05:00 Document RTS behaviour upon encountering '--'. - - - - - 705a16df by Ben Gamari at 2019-12-03T07:11:33-05:00 Make BCO# lifted In #17424 Simon PJ noted that there is a potentially unsafe occurrence of unsafeCoerce#, coercing from an unlifted to lifted type. However, nowhere in the compiler do we assume that a BCO# is not a thunk. Moreover, in the case of a CAF the result returned by `createBCO` *will* be a thunk (as noted in [Updatable CAF BCOs]). Consequently it seems better to rather make BCO# a lifted type and rename it to BCO. - - - - - 35afe4f3 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Use Int# primops in `Bits Int{8,16,32,64}` instances - - - - - 7a51b587 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Add constant folding rule (#16402) narrowN (x .&. m) m .&. (2^N-1) = 2^N-1 ==> narrowN x e.g. narrow16 (x .&. 0x12FFFF) ==> narrow16 x - - - - - 10caee7f by Ben Gamari at 2019-12-03T21:04:50-05:00 users-guide: Add 8.12.1 release notes - - - - - 25019d18 by Ben Gamari at 2019-12-03T21:04:50-05:00 Drop Uniquable constraint for AnnTarget This relied on deriveUnique, which was far too subtle to be safely applied. Thankfully the instance doesn't appear to be used so let's just drop it. - - - - - 78b67ad0 by Ben Gamari at 2019-12-03T21:04:50-05:00 Simplify uniqAway This does two things: * Eliminate all uses of Unique.deriveUnique, which was quite easy to mis-use and extremely subtle. * Rename the previous "derived unique" notion to "local unique". This is possible because the only places where `uniqAway` can be safely used are those where local uniqueness (with respect to some InScopeSet) is sufficient. * Rework the implementation of VarEnv.uniqAway, as discussed in #17462. This should make the operation significantly more efficient than its previous iterative implementation.. Metric Decrease: T9872c T12227 T9233 T14683 T5030 T12545 hie002 Metric Increase: T9961 - - - - - f03a41d4 by Ben Gamari at 2019-12-03T21:05:27-05:00 Elf: Fix link info note generation Previously we would use the `.int` assembler directive to generate 32-bit words in the note section. However, `.int` is note guaranteed to produce 4-bytes; in fact, on some platforms (e.g. AArch64) it produces 8-bytes. Use the `.4bytes` directive to avoid this. Moreover, we used the `.align` directive, which is quite platform dependent. On AArch64 it appears to not even be idempotent (despite what the documentation claims). `.balign` is consequentially preferred as it offers consistent behavior across platforms. - - - - - 84585e5e by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Meaning-preserving SCC annotations (#15730) This patch implements GHC Proposal #176: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0176-scc-parsing.rst Before the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = 1.0 After the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = parse error - - - - - e49e5470 by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Improve error messages for SCC pragmas - - - - - a2b535d9 by Ben Gamari at 2019-12-05T16:07:45-05:00 users guide: Try to silence underfull \hbox warnings We use two tricks, as suggested here [1]: * Use microtype to try to reduce the incidence of underfull boxes * Bump up \hbadness to eliminate the warnings - - - - - 4e47217f by Bodigrim at 2019-12-05T16:07:47-05:00 Make sameNat and sameSymbol proxy-polymorphic - - - - - 8324f0b7 by Bodigrim at 2019-12-05T16:07:47-05:00 Test proxy-polymorphic sameNat and sameSymbol - - - - - 69001f54 by Ben Gamari at 2019-12-05T16:07:48-05:00 nonmoving: Clear segment bitmaps during sweep Previously we would clear the bitmaps of segments which we are going to sweep during the preparatory pause. However, this is unnecessary: the existence of the mark epoch ensures that the sweep will correctly identify non-reachable objects, even if we do not clear the bitmap. We now defer clearing the bitmap to sweep, which happens concurrently with mutation. - - - - - 58a9c429 by Ben Gamari at 2019-12-05T16:07:48-05:00 testsuite: Disable divByZero on non-NCG targets The LLVM backend does not guarantee any particular semantics for division by zero, making this test unreliable across platforms. - - - - - 8280bd8a by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Factor out terminal coloring - - - - - 92a52aaa by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Make performance metric summary more readable Along with some refactoring. - - - - - c4ca29c7 by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Use colors more consistently - - - - - 3354c68e by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Pretty-printing of the * kind Before this patch, GHC always printed the * kind unparenthesized. This led to two issues: 1. Sometimes GHC printed invalid or incorrect code. For example, GHC would print: type F @* x = x when it meant to print: type F @(*) x = x In the former case, instead of a kind application we were getting a type operator (@*). 2. Sometimes GHC printed kinds that were correct but hard to read. Should Either * Int be read as Either (*) Int or as (*) Either Int ? This depends on whether -XStarIsType is enabled, but it would be easier if we didn't have to check for the flag when reading the code. We can solve both problems by assigning (*) a different precedence. Note that Haskell98 kinds are not affected: ((* -> *) -> *) -> * does NOT become (((*) -> (*)) -> (*)) -> (*) The parentheses are added when (*) is used in a function argument position: F * * * becomes F (*) (*) (*) F A * B becomes F A (*) B Proxy * becomes Proxy (*) a * -> * becomes a (*) -> * - - - - - 70dd0e4b by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Parenthesize the * kind in TH.Ppr - - - - - a7a4efbf by Ben Gamari at 2019-12-05T16:07:49-05:00 rts/NonMovingSweep: Fix locking of new mutable list allocation Previously we used allocBlockOnNode_sync in nonmovingSweepMutLists despite the fact that we aren't in the GC and therefore the allocation spinlock isn't in use. This meant that sweep would end up spinning until the next minor GC, when the SM lock was moved away from the SM_MUTEX to the spinlock. This isn't a correctness issue but it sure isn't good for performance. Found thanks for Ward. Fixes #17539. - - - - - f171b358 by Matthias Braun at 2019-12-05T16:07:51-05:00 Fix typo in documentation of Base.hs. - - - - - 9897e8c8 by Gabor Greif at 2019-12-06T21:20:38-05:00 Implement pointer tagging for big families (#14373) Formerly we punted on these and evaluated constructors always got a tag of 1. We now cascade switches because we have to check the tag first and when it is MAX_PTR_TAG then get the precise tag from the info table and switch on that. The only technically tricky part is that the default case needs (logical) duplication. To do this we emit an extra label for it and branch to that from the second switch. This avoids duplicated codegen. Here's a simple example of the new code gen: data D = D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 On a 64-bit system previously all constructors would be tagged 1. With the new code gen D7 and D8 are tagged 7: [Lib.D7_con_entry() { ... {offset c1eu: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] [Lib.D8_con_entry() { ... {offset c1ez: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] When switching we now look at the info table only when the tag is 7. For example, if we derive Enum for the type above, the Cmm looks like this: c2Le: _s2Js::P64 = R1; _c2Lq::P64 = _s2Js::P64 & 7; switch [1 .. 7] _c2Lq::P64 { case 1 : goto c2Lk; case 2 : goto c2Ll; case 3 : goto c2Lm; case 4 : goto c2Ln; case 5 : goto c2Lo; case 6 : goto c2Lp; case 7 : goto c2Lj; } // Read info table for tag c2Lj: _c2Lv::I64 = %MO_UU_Conv_W32_W64(I32[I64[_s2Js::P64 & (-8)] - 4]); if (_c2Lv::I64 != 6) goto c2Lu; else goto c2Lt; Generated Cmm sizes do not change too much, but binaries are very slightly larger, due to the fact that the new instructions are longer in encoded form. E.g. previously entry code for D8 above would be 00000000000001c0 <Lib_D8_con_info>: 1c0: 48 ff c3 inc %rbx 1c3: ff 65 00 jmpq *0x0(%rbp) With this patch 00000000000001d0 <Lib_D8_con_info>: 1d0: 48 83 c3 07 add $0x7,%rbx 1d4: ff 65 00 jmpq *0x0(%rbp) This is one byte longer. Secondly, reading info table directly and then switching is shorter _c1co: movq -1(%rbx),%rax movl -4(%rax),%eax // Switch on info table tag jmp *_n1d5(,%rax,8) than doing the same switch, and then for the tag 7 doing another switch: // When tag is 7 _c1ct: andq $-8,%rbx movq (%rbx),%rax movl -4(%rax),%eax // Switch on info table tag ... Some changes of binary sizes in actual programs: - In NoFib the worst case is 0.1% increase in benchmark "parser" (see NoFib results below). All programs get slightly larger. - Stage 2 compiler size does not change. - In "containers" (the library) size of all object files increases 0.0005%. Size of the test program "bitqueue-properties" increases 0.03%. nofib benchmarks kindly provided by Ömer (@osa1): NoFib Results ============= -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.0% 0.0% -0.0% -0.0% -0.0% CSD +0.0% 0.0% 0.0% +0.0% +0.0% FS +0.0% 0.0% 0.0% +0.0% 0.0% S +0.0% 0.0% -0.0% 0.0% 0.0% VS +0.0% 0.0% -0.0% +0.0% +0.0% VSD +0.0% 0.0% -0.0% +0.0% -0.0% VSM +0.0% 0.0% 0.0% 0.0% 0.0% anna +0.0% 0.0% +0.1% -0.9% -0.0% ansi +0.0% 0.0% -0.0% +0.0% +0.0% atom +0.0% 0.0% 0.0% 0.0% 0.0% awards +0.0% 0.0% -0.0% +0.0% 0.0% banner +0.0% 0.0% -0.0% +0.0% 0.0% bernouilli +0.0% 0.0% +0.0% +0.0% +0.0% binary-trees +0.0% 0.0% -0.0% -0.0% -0.0% boyer +0.0% 0.0% +0.0% 0.0% -0.0% boyer2 +0.0% 0.0% +0.0% 0.0% -0.0% bspt +0.0% 0.0% +0.0% +0.0% 0.0% cacheprof +0.0% 0.0% +0.1% -0.8% 0.0% calendar +0.0% 0.0% -0.0% +0.0% -0.0% cichelli +0.0% 0.0% +0.0% 0.0% 0.0% circsim +0.0% 0.0% -0.0% -0.1% -0.0% clausify +0.0% 0.0% +0.0% +0.0% 0.0% comp_lab_zift +0.0% 0.0% +0.0% 0.0% -0.0% compress +0.0% 0.0% +0.0% +0.0% 0.0% compress2 +0.0% 0.0% 0.0% 0.0% 0.0% constraints +0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 +0.0% 0.0% +0.0% 0.0% 0.0% cryptarithm2 +0.0% 0.0% +0.0% -0.0% 0.0% cse +0.0% 0.0% +0.0% +0.0% 0.0% digits-of-e1 +0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 +0.0% 0.0% +0.0% -0.0% -0.0% dom-lt +0.0% 0.0% +0.0% +0.0% 0.0% eliza +0.0% 0.0% -0.0% +0.0% 0.0% event +0.0% 0.0% -0.0% -0.0% -0.0% exact-reals +0.0% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.0% 0.0% -0.0% -0.0% -0.0% expert +0.0% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.0% 0.0% +0.0% 0.0% 0.0% fasta +0.0% 0.0% -0.0% -0.0% -0.0% fem +0.0% 0.0% +0.0% +0.0% +0.0% fft +0.0% 0.0% +0.0% -0.0% -0.0% fft2 +0.0% 0.0% +0.0% +0.0% +0.0% fibheaps +0.0% 0.0% +0.0% +0.0% 0.0% fish +0.0% 0.0% +0.0% +0.0% 0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.0% 0.0% +0.0% -0.0% +0.0% gamteb +0.0% 0.0% +0.0% -0.0% -0.0% gcd +0.0% 0.0% +0.0% +0.0% 0.0% gen_regexps +0.0% 0.0% +0.0% -0.0% -0.0% genfft +0.0% 0.0% -0.0% -0.0% -0.0% gg +0.0% 0.0% 0.0% -0.0% 0.0% grep +0.0% 0.0% +0.0% +0.0% +0.0% hidden +0.0% 0.0% +0.0% -0.0% -0.0% hpg +0.0% 0.0% +0.0% -0.1% -0.0% ida +0.0% 0.0% +0.0% -0.0% -0.0% infer +0.0% 0.0% -0.0% -0.0% -0.0% integer +0.0% 0.0% -0.0% -0.0% -0.0% integrate +0.0% 0.0% 0.0% +0.0% 0.0% k-nucleotide +0.0% 0.0% -0.0% -0.0% -0.0% kahan +0.0% 0.0% -0.0% -0.0% -0.0% knights +0.0% 0.0% +0.0% -0.0% -0.0% lambda +0.0% 0.0% +1.2% -6.1% -0.0% last-piece +0.0% 0.0% +0.0% -0.0% -0.0% lcss +0.0% 0.0% +0.0% -0.0% -0.0% life +0.0% 0.0% +0.0% -0.0% -0.0% lift +0.0% 0.0% +0.0% +0.0% 0.0% linear +0.0% 0.0% +0.0% +0.0% +0.0% listcompr +0.0% 0.0% -0.0% -0.0% -0.0% listcopy +0.0% 0.0% -0.0% -0.0% -0.0% maillist +0.0% 0.0% +0.0% -0.0% -0.0% mandel +0.0% 0.0% +0.0% +0.0% +0.0% mandel2 +0.0% 0.0% +0.0% +0.0% -0.0% mate +0.0% 0.0% +0.0% +0.0% +0.0% minimax +0.0% 0.0% -0.0% +0.0% -0.0% mkhprog +0.0% 0.0% +0.0% +0.0% +0.0% multiplier +0.0% 0.0% 0.0% +0.0% -0.0% n-body +0.0% 0.0% +0.0% -0.0% -0.0% nucleic2 +0.0% 0.0% +0.0% +0.0% -0.0% para +0.0% 0.0% +0.0% +0.0% +0.0% paraffins +0.0% 0.0% +0.0% +0.0% +0.0% parser +0.1% 0.0% +0.4% -1.7% -0.0% parstof +0.0% 0.0% -0.0% -0.0% -0.0% pic +0.0% 0.0% +0.0% 0.0% -0.0% pidigits +0.0% 0.0% -0.0% -0.0% -0.0% power +0.0% 0.0% +0.0% -0.0% -0.0% pretty +0.0% 0.0% +0.0% +0.0% +0.0% primes +0.0% 0.0% +0.0% 0.0% 0.0% primetest +0.0% 0.0% +0.0% +0.0% +0.0% prolog +0.0% 0.0% +0.0% +0.0% +0.0% puzzle +0.0% 0.0% +0.0% +0.0% +0.0% queens +0.0% 0.0% 0.0% +0.0% +0.0% reptile +0.0% 0.0% +0.0% +0.0% 0.0% reverse-complem +0.0% 0.0% -0.0% -0.0% -0.0% rewrite +0.0% 0.0% +0.0% 0.0% -0.0% rfib +0.0% 0.0% +0.0% +0.0% +0.0% rsa +0.0% 0.0% +0.0% +0.0% +0.0% scc +0.0% 0.0% +0.0% +0.0% +0.0% sched +0.0% 0.0% +0.0% +0.0% +0.0% scs +0.0% 0.0% +0.0% +0.0% 0.0% simple +0.0% 0.0% +0.0% +0.0% +0.0% solid +0.0% 0.0% +0.0% +0.0% 0.0% sorting +0.0% 0.0% +0.0% -0.0% 0.0% spectral-norm +0.0% 0.0% -0.0% -0.0% -0.0% sphere +0.0% 0.0% +0.0% -1.0% 0.0% symalg +0.0% 0.0% +0.0% +0.0% +0.0% tak +0.0% 0.0% +0.0% +0.0% +0.0% transform +0.0% 0.0% +0.4% -1.3% +0.0% treejoin +0.0% 0.0% +0.0% -0.0% 0.0% typecheck +0.0% 0.0% -0.0% +0.0% 0.0% veritas +0.0% 0.0% +0.0% -0.1% +0.0% wang +0.0% 0.0% +0.0% +0.0% +0.0% wave4main +0.0% 0.0% +0.0% 0.0% -0.0% wheel-sieve1 +0.0% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.0% 0.0% +0.0% +0.0% 0.0% x2n1 +0.0% 0.0% +0.0% +0.0% 0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -6.1% -0.0% Max +0.1% 0.0% +1.2% +0.0% +0.0% Geometric Mean +0.0% -0.0% +0.0% -0.1% -0.0% NoFib GC Results ================ -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim +0.0% 0.0% -0.0% -0.0% -0.0% constraints +0.0% 0.0% -0.0% 0.0% -0.0% fibheaps +0.0% 0.0% 0.0% -0.0% -0.0% fulsom +0.0% 0.0% 0.0% -0.6% -0.0% gc_bench +0.0% 0.0% 0.0% 0.0% -0.0% hash +0.0% 0.0% -0.0% -0.0% -0.0% lcss +0.0% 0.0% 0.0% -0.0% 0.0% mutstore1 +0.0% 0.0% 0.0% -0.0% -0.0% mutstore2 +0.0% 0.0% +0.0% -0.0% -0.0% power +0.0% 0.0% -0.0% 0.0% -0.0% spellcheck +0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.6% -0.0% Max +0.0% 0.0% +0.0% 0.0% 0.0% Geometric Mean +0.0% +0.0% +0.0% -0.1% +0.0% Fixes #14373 These performance regressions appear to be a fluke in CI. See the discussion in !1742 for details. Metric Increase: T6048 T12234 T12425 Naperian T12150 T5837 T13035 - - - - - ee07421f by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Work in progress on coercionLKind, coercionRKind This is a preliminary patch for #17515 - - - - - 0a4ca9eb by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Split up coercionKind This patch implements the idea in #17515, splitting `coercionKind` into: * `coercion{Left,Right}Kind`, which computes the left/right side of the pair * `coercionKind`, which computes the pair of coercible types This is reduces allocation since we frequently only need only one side of the pair. Specifically, we see the following improvements on x86-64 Debian 9: | test | new | old | relative chg. | | :------- | ---------: | ------------: | ------------: | | T5030 | 695537752 | 747641152.0 | -6.97% | | T5321Fun | 449315744 | 474009040.0 | -5.21% | | T9872a | 2611071400 | 2645040952.0 | -1.28% | | T9872c | 2957097904 | 2994260264.0 | -1.24% | | T12227 | 773435072 | 812367768.0 | -4.79% | | T12545 | 3142687224 | 3215714752.0 | -2.27% | | T14683 | 9392407664 | 9824775000.0 | -4.40% | Metric Decrease: T12545 T9872a T14683 T5030 T12227 T9872c T5321Fun T9872b - - - - - d46a72e1 by Gabor Greif at 2019-12-09T12:05:15-05:00 Fix comment typos The below is only necessary to fix the CI perf fluke that happened in 9897e8c8ef0b19a9571ef97a1d9bb050c1ee9121: ------------------------- Metric Decrease: T5837 T6048 T9020 T12425 T12234 T13035 T12150 Naperian ------------------------- - - - - - e3bba7e4 by Micha Wiedenmann at 2019-12-10T19:52:44-05:00 users guide: Motivation of DefaultSignatures - - - - - 843ceb38 by Ben Gamari at 2019-12-10T19:53:54-05:00 rts: Add a long form flag to enable the non-moving GC The old flag, `-xn`, was quite cryptic. Here we add `--nonmoving-gc` in addition. - - - - - 921d3238 by Ryan Scott at 2019-12-10T19:54:34-05:00 Ignore unary constraint tuples during typechecking (#17511) We deliberately avoid defining a magical `Unit%` class, for reasons that I have expounded upon in the newly added `Note [Ignore unary constraint tuples]` in `TcHsType`. However, a sneaky user could try to insert `Unit%` into their program by way of Template Haskell, leading to the interface-file error observed in #17511. To avoid this, any time we encounter a unary constraint tuple during typechecking, we drop the surrounding constraint tuple application. This is safe to do since `Unit% a` and `a` would be semantically equivalent (unlike other forms of unary tuples). Fixes #17511. - - - - - 436ec9f3 by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 2f6b434f by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 7a5a6e07 by Ben Gamari at 2019-12-10T19:56:25-05:00 base: Fix incorrect @since in GHC.Natural Fixes #17547. - - - - - 2bbfaf8a by Ben Gamari at 2019-12-10T19:57:01-05:00 hadrian: AArch64 supports the GHCi interpreter and SMP I'm not sure how this was omitted from the list of supported architectures. - - - - - 8f1ceb67 by John Ericson at 2019-12-10T19:57:39-05:00 Move Int# section of primops.txt.pp This matches the organization of the fixed-sized ones, and keeps each Int* next to its corresponding Word*. - - - - - 7a823b0f by John Ericson at 2019-12-10T19:57:39-05:00 Move Int64# and Word64# sections of primops.txt.pp This way it is next to the other fixed-sized ones. - - - - - 8dd9929a by Ben Gamari at 2019-12-10T19:58:19-05:00 testsuite: Add (broken) test for #17510 - - - - - 6e47a76a by Ben Gamari at 2019-12-10T19:58:59-05:00 Re-layout validate script This script was previously a whitespace nightmare. - - - - - f80c4a66 by Crazycolorz5 at 2019-12-11T14:12:17-05:00 rts: Specialize hashing at call site rather than in struct. Separate word and string hash tables on the type level, and do not store the hashing function. Thus when a different hash function is desire it is provided upon accessing the table. This is worst case the same as before the change, and in the majority of cases is better. Also mark the functions for aggressive inlining to improve performance. {F1686506} Reviewers: bgamari, erikd, simonmar Subscribers: rwbarton, thomie, carter GHC Trac Issues: #13165 Differential Revision: https://phabricator.haskell.org/D4889 - - - - - 2d1b9619 by Richard Eisenberg at 2019-12-11T14:12:55-05:00 Warn on inferred polymorphic recursion Silly users sometimes try to use visible dependent quantification and polymorphic recursion without a CUSK or SAK. This causes unexpected errors. So we now adjust expectations with a bit of helpful messaging. Closes #17541 and closes #17131. test cases: dependent/should_fail/T{17541{,b},17131} - - - - - 4dde485e by Oleg Grenrus at 2019-12-12T02:24:46-05:00 Add --show-unit-ids flag to ghc-pkg I only added it into --simple-output and ghc-pkg check output; there are probably other places where it can be adopted. - - - - - e6e1ec08 by Ben Gamari at 2019-12-12T02:25:33-05:00 testsuite: Simplify and clarify performance test baseline search The previous implementation was extremely complicated, seemingly to allow the local and CI namespaces to be searched incrementally. However, it's quite unclear why this is needed and moreover the implementation seems to have had quadratic runtime cost in the search depth(!). - - - - - 29c4609c by Ben Gamari at 2019-12-12T02:26:19-05:00 testsuite: Add test for #17549 - - - - - 9f0ee253 by Ben Gamari at 2019-12-12T02:26:56-05:00 gitlab-ci: Move -dwarf and -debug jobs to full-build stage This sacrifices some precision in favor of improving parallelism. - - - - - 7179b968 by Ben Gamari at 2019-12-12T02:27:34-05:00 Revert "rts: Drop redundant flags for libffi" This seems to have regressed builds using `--with-system-libffi` (#17520). This reverts commit 3ce18700f80a12c48a029b49c6201ad2410071bb. - - - - - cc7d5650 by Oleg Grenrus at 2019-12-16T10:20:56+02:00 Having no shake upper bound is irresposible Given that shake is far from "done" API wise, and is central component to the build system. - - - - - 9431f905 by Oleg Grenrus at 2019-12-16T10:55:50+02:00 Add index-state to hadrian/cabal.project Then one is freer to omit upper bounds, as we won't pick any new entries on Hackage while building hadrian itself. - - - - - 3e17a866 by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Remove dataConSig As suggested in #17291 - - - - - 75355fde by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Use "OrCoVar" functions less As described in #17291, we'd like to separate coercions and expressions in a more robust fashion. This is a small step in this direction. - `mkLocalId` now panicks on a covar. Calls where this was not the case were changed to `mkLocalIdOrCoVar`. - Don't use "OrCoVar" functions in places where we know the type is not a coercion. - - - - - f9686e13 by Richard Eisenberg at 2019-12-16T19:32:21-05:00 Do more validity checks for quantified constraints Close #17583. Test case: typecheck/should_fail/T17563 - - - - - af763765 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Fix Windows artifact collection Variable interpolation in gitlab-ci.yml apparently doesn't work. Sigh. - - - - - e6d4b902 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Debian 10 - - - - - 8ba650e9 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Allow debian 8 build to fail The python release shipped with deb8 (3.3) is too old for our testsuite driver. - - - - - ac25a3f6 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Alpine - - - - - cc628088 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Another approach for xz detection - - - - - 37d788ab by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Re-add release-x86_64-deb9 job Also eliminate some redundancy. - - - - - f8279138 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Drop redundant release-x86_64-linux-deb9 job - - - - - 8148ff06 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark cgrun057 as broken on ARMv7 Due to #17554. It's very surprising that this only occurs on ARMv7 but this is the only place I've seen this failure thusfar. - - - - - 85e5696d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark prog001 as fragile on ARMv7 Due to #17555. - - - - - a5f0aab0 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T10272 as broken on ARMv7 Due to #17556. - - - - - 1e6827c6 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T13825-debugger as broken on ARMv7 Due to #17557. - - - - - 7cef0b7d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T14028 as broken on ARMv7 Due to #17558. - - - - - 6ea4eb4b by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Make ghc_built_by_llvm check more precise Previously it would hackily look at the flavour name to determine whether LLVM was used to build stage2 ghc. However, this didn't work at all with Hadrian and would miss cases like ARM where we use the LLVM backend by default. See #16087 for the motivation for why ghc_built_by_llvm is needed at all. This should catch one of the ARMv7 failures described in #17555. - - - - - c3e82bf7 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T5435_* tests as broken on ARM `T5435_v_asm_a`, `T5435_v_asm_b`, and `T5435_v_gcc` all fail on ARMv7. See #17559. - - - - - eb2aa851 by Ben Gamari at 2019-12-17T07:24:40-05:00 gitlab-ci: Don't allow armv7 jobs to fail - - - - - efc92216 by Ben Gamari at 2019-12-17T07:24:40-05:00 Revert "testsuite: Mark cgrun057 as broken on ARMv7" This reverts commit 6cfc47ec8a478e1751cb3e7338954da1853c3996. - - - - - 1d2bb9eb by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark print002 as fragile on ARM Due to #17557. Also accepting spurious performance change. Metric Decrease: T1969 - - - - - 41f4e4fb by Josh Meredith at 2019-12-17T07:25:17-05:00 Fix ambiguous occurence error when building Hadrian - - - - - 4374983a by Josh Meredith at 2019-12-17T07:25:17-05:00 Rename SphinxMode constructors - - - - - a8f7ecd5 by Josh Meredith at 2019-12-17T07:25:17-05:00 Use *Mode suffix instead of *M - - - - - 58655b9d by Sylvain Henry at 2019-12-18T13:43:37+01:00 Add GHC-API logging hooks * Add 'dumpAction' hook to DynFlags. It allows GHC API users to catch dumped intermediate codes and information. The format of the dump (Core, Stg, raw text, etc.) is now reported allowing easier automatic handling. * Add 'traceAction' hook to DynFlags. Some dumps go through the trace mechanism (for instance unfoldings that have been considered for inlining). This is problematic because: 1) dumps aren't written into files even with -ddump-to-file on 2) dumps are written on stdout even with GHC API 3) in this specific case, dumping depends on unsafe globally stored DynFlags which is bad for GHC API users We introduce 'traceAction' hook which allows GHC API to catch those traces and to avoid using globally stored DynFlags. * Avoid dumping empty logs via dumpAction/traceAction (but still write empty files to keep the existing behavior) - - - - - fad866e0 by Moritz Kiefer at 2019-12-19T11:15:39-05:00 Avoid race condition in hDuplicateTo In our codebase we have some code along the lines of ``` newStdout <- hDuplicate stdout stderr `hDuplicateTo` stdout ``` to avoid stray `putStrLn`s from corrupting a protocol (LSP) that is run over stdout. On CI we have seen a bunch of issues where `dup2` returned `EBUSY` so this fails with `ResourceExhausted` in Haskell. I’ve spent some time looking at the docs for `dup2` and the code in `base` and afaict the following race condition is being triggered here: 1. The user calls `hDuplicateTo stderr stdout`. 2. `hDuplicateTo` calls `hClose_help stdout_`, this closes the file handle for stdout. 3. The file handle for stdout is now free, so another thread allocating a file might get stdout. 4. If `dup2` is called while `stdout` (now pointing to something else) is half-open, it returns EBUSY. I think there might actually be an even worse case where `dup2` is run after FD 1 is fully open again. In that case, you will end up not just redirecting the original stdout to stderr but also the whatever resulted in that file handle being allocated. As far as I can tell, `dup2` takes care of closing the file handle itself so there is no reason to do this in `hDuplicateTo`. So this PR replaces the call to `hClose_help` by the only part of `hClose_help` that we actually care about, namely, `flushWriteBuffer`. I tested this on our codebase fairly extensively and haven’t been able to reproduce the issue with this patch. - - - - - 0c114c65 by Sylvain Henry at 2019-12-19T11:16:17-05:00 Handle large ARR_WORDS in heap census (fix #17572) We can do a heap census with a non-profiling RTS. With a non-profiling RTS we don't zero superfluous bytes of shrunk arrays hence a need to handle the case specifically to avoid a crash. Revert part of a586b33f8e8ad60b5c5ef3501c89e9b71794bbed - - - - - 1a0d1a65 by John Ericson at 2019-12-20T10:50:22-05:00 Deduplicate copied monad failure handler code - - - - - 70e56b27 by Ryan Scott at 2019-12-20T10:50:57-05:00 lookupBindGroupOcc: recommend names in the same namespace (#17593) Previously, `lookupBindGroupOcc`'s error message would recommend all similar names in scope, regardless of whether they were type constructors, data constructors, or functions, leading to the confusion witnessed in #17593. This is easily fixed by only recommending names in the same namespace, using the `nameSpacesRelated` function. Fixes #17593. - - - - - 3c12355e by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN Include header file `ghcautoconf.h` where the CPP macro `WORDS_BIGENDIAN` is defined. This finally fixes #17337 (in conjunction with commit 6c59cc71dc). - - - - - 11f8eef5 by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 fixup! Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN - - - - - 40327b03 by Sylvain Henry at 2019-12-24T01:04:24-05:00 Remove outdated comment - - - - - aeea92ef by Sylvain Henry at 2019-12-25T19:23:54-05:00 Switch to ReadTheDocs theme for the user-guide - - - - - 26493eab by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix copy-paste error in comment - - - - - 776df719 by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix comment about minimal gcc version to be consistent what FP_GCC_VERSION requires - - - - - 3b17114d by Ömer Sinan Ağacan at 2019-12-26T14:09:11-05:00 Minor refactor in ghc.cabal.in: - Remove outdated comments - Move cutils.c from parser to cbits - Remove unused cutils.h - - - - - 334290b6 by Ryan Scott at 2019-12-26T14:09:48-05:00 Replace panic/notHandled with noExtCon in DsMeta There are many spots in `DsMeta` where `panic` or `notHandled` is used after pattern-matching on a TTG extension constructor. This is overkill, however, as using `noExtCon` would work just as well. This patch switches out these panics for `noExtCon`. - - - - - 68252aa3 by Ben Gamari at 2019-12-27T15:11:38-05:00 testsuite: Skip T17499 when built against integer-simple Since it routinely times out in CI. - - - - - 0c51aeeb by Gabor Greif at 2019-12-27T15:12:17-05:00 suppress popup dialog about missing Xcode at configure tested with `bash` and `zsh`. - - - - - 8d76bcc2 by Gabor Greif at 2019-12-27T15:12:17-05:00 while at it rename XCode to the official Xcode - - - - - 47a68205 by Ben Gamari at 2019-12-27T15:12:55-05:00 testsuite: Mark cgrun057 as fragile on ARM As reported in #17554. Only marking on ARM for now although there is evidence to suggest that the issue may occur on other platforms as well. - - - - - d03dec8f by Gabor Greif at 2019-12-27T15:13:32-05:00 use shell variable CcLlvmBackend for test Previously we used `AC_DEFINE`d variable `CC_LLVM_BACKEND` which has an empty shell expansion. - - - - - 2528e684 by Ben Gamari at 2019-12-30T06:51:32-05:00 driver: Include debug level in the recompilation check hash Fixes #17586. - - - - - f14bb50b by Ben Gamari at 2019-12-30T06:52:09-05:00 rts: Ensure that nonmoving gc isn't used with profiling - - - - - b426de37 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Ensure that entry labels don't have predecessors The LLVM IR forbids the entry label of a procedure from having any predecessors. In the case of a simple looping function the LLVM code generator broke this invariant, as noted in #17589. Fix this by moving the function prologue to its own basic block, as suggested by @kavon in #11649. Fixes #11649 and #17589. - - - - - 613f7265 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Drop old fix for #11649 This was a hack which is no longer necessary now since we introduce a dedicated entry block for each procedure. - - - - - fdeffa5e by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Error on invalid --numa flags Previously things like `+RTS --numa-debug` would enable NUMA support, despite being an invalid flag. - - - - - 9ce3ba68 by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Fix --debug-numa mode under Docker As noted in #17606, Docker disallows the get_mempolicy syscall by default. This caused numerous tests to fail under CI in the `debug_numa` way. Avoid this by disabling the NUMA probing logic when --debug-numa is in use, instead setting n_numa_nodes in RtsFlags.c. Fixes #17606. - - - - - 5baa2a43 by Ben Gamari at 2019-12-30T06:54:01-05:00 testsuite: Disable derefnull when built with LLVM LLVM does not guarantee any particular semantics when dereferencing null pointers. Consequently, this test actually passes when built with the LLVM backend. - - - - - bd544d3d by Ben Gamari at 2019-12-30T06:54:38-05:00 hadrian: Track hash of Cabal Setup builder arguments Lest we fail to rebuild when they change. Fixes #17611. - - - - - 6e2c495e by Ben Gamari at 2019-12-30T06:55:19-05:00 TcIface: Fix inverted logic in typechecking of source ticks Previously we would throw away source ticks when the debug level was non-zero. This is precisely the opposite of what was intended. Fixes #17616. Metric Decrease: T13056 T9020 T9961 T12425 - - - - - 7fad387d by Ben Gamari at 2019-12-30T06:55:55-05:00 perf_notes: Add --zero-y argument This makes it easier to see the true magnitude of fluctuations. Also do some house-keeping in the argument parsing department. - - - - - 0d42b287 by Ben Gamari at 2019-12-30T06:55:55-05:00 testsuite: Enlarge acceptance window for T1969 As noted in #17624, it's quite unstable, especially, for some reason, on i386 and armv7 (something about 32-bit platforms perhaps?). Metric Increase: T1969 - - - - - eb608235 by Sylvain Henry at 2019-12-31T14:22:32-05:00 Module hierarchy (#13009): Stg - - - - - d710fd66 by Vladislav Zavialov at 2019-12-31T14:23:10-05:00 Testsuite: update some Haddock tests Fixed tests: * haddockA039: added to all.T * haddockE004: replaced with T17561 (marked as expect_broken) New tests: * haddockA040: deriving clause for a data instance * haddockA041: haddock and CPP #include - - - - - 859ebdd4 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add "-Iw" RTS flag for minimum wait between idle GCs (#11134) - - - - - dd4b6551 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add additional Note explaining the -Iw flag - - - - - c4279ff1 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Fix some sloppy indentation - - - - - b84c09d5 by Ömer Sinan Ağacan at 2019-12-31T23:45:19-05:00 Tweak Cmm dumps to avoid generating sections for empty groups When dumping Cmm groups check if the group is empty, to avoid generating empty sections in dump files like ==================== Output Cmm ==================== [] Also fixes a few bad indentation in the code around changes. - - - - - b2e0323f by Gabor Greif at 2020-01-03T21:22:36-05:00 Simplify mrStr - - - - - 3c9dc06b by Brian Wignall at 2020-01-04T15:55:06-05:00 Fix typos, via a Levenshtein-style corrector - - - - - d561c8f6 by Sylvain Henry at 2020-01-04T15:55:46-05:00 Add Cmm related hooks * stgToCmm hook * cmmToRawCmm hook These hooks are used by Asterius and could be useful to other clients of the GHC API. It increases the Parser dependencies (test CountParserDeps) to 184. It's still less than 200 which was the initial request (cf https://mail.haskell.org/pipermail/ghc-devs/2019-September/018122.html) so I think it's ok to merge this. - - - - - ae6b6276 by Oleg Grenrus at 2020-01-04T15:56:22-05:00 Update to Cabal submodule to v3.2.0.0-alpha3 Metric Increase: haddock.Cabal - - - - - 073f7cfd by Vladislav Zavialov at 2020-01-04T15:56:59-05:00 Add lexerDbg to dump the tokens fed to the parser This a small utility function that comes in handy when debugging the lexer and the parser. - - - - - 558d4d4a by Sylvain Henry at 2020-01-04T15:57:38-05:00 Split integerGmpInternals test in several parts This is to prepare for ghc-bignum which implements some but not all of gmp functions. - - - - - 4056b966 by Ben Gamari at 2020-01-04T15:58:15-05:00 testsuite: Mark cgrun057 as fragile on all platforms I have seen this fail both on x86-64/Debian 9 and armv7/Debian 9 See #17554. - - - - - 5ffea0c6 by Tamar Christina at 2020-01-06T18:38:37-05:00 Fix overflow. - - - - - 99a9f51b by Sylvain Henry at 2020-01-06T18:39:22-05:00 Module hierarchy: Iface (cf #13009) - - - - - 7aa4a061 by Ben Gamari at 2020-01-07T13:11:48-05:00 configure: Only check GCC version if CC is GCC Also refactor FP_GCC_EXTRA_FLAGS in a few ways: * We no longer support compilers which lack support for -fno-builtin and -fwrapv so remove the condition on GccVersion * These flags are only necessary when using the via-C backend so make them conditional on Unregisterised. Fixes #15742. - - - - - 0805ed7e by John Ericson at 2020-01-07T13:12:25-05:00 Use non-empty lists to remove partiality in matching code - - - - - 7844f3a8 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Mark T17073 as broken on Windows Due to #17607. - - - - - acf40cae by Ben Gamari at 2020-01-07T13:13:02-05:00 gitlab-ci: Disallow Windows from failing - - - - - 34bc02c7 by Ben Gamari at 2020-01-07T13:13:02-05:00 configure: Find Python3 for testsuite In addition, we prefer the Mingw64 Python distribution on Windows due to #17483. - - - - - e35fe8d5 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Fix Windows platform test Previously we used platform.system() and while this worked fine (e.g. returned `Windows`, as expected) locally under both msys and MingW64 Python distributions, it inexplicably returned `MINGW64_NT-10.0` under MingW64 Python on CI. It seems os.name is more reliable so we now use that instead.. - - - - - 48ef6217 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Rename push-test-metrics.sh to test-metrics.sh Refactoring to follow. - - - - - 2234fa92 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Pull test metrics before running testsuite Otherwise the testsuite driver may not have an up-to-date baseline. - - - - - 1ca9adbc by Sylvain Henry at 2020-01-07T13:14:18-05:00 Remove `parallel` check from configure.ac `parallel` is no longer a submodule since 3cb063c805ec841ca33b8371ef8aba9329221b6c - - - - - b69a3460 by Ryan Scott at 2020-01-07T13:14:57-05:00 Monomorphize HsModule to GhcPs (#17642) Analyzing the call sites for `HsModule` reveals that it is only ever used with parsed code (i.e., `GhcPs`). This simplifies `HsModule` by concretizing its `pass` parameter to always be `GhcPs`. Fixes #17642. - - - - - d491a679 by Sylvain Henry at 2020-01-08T06:16:31-05:00 Module hierarchy: Renamer (cf #13009) - - - - - d589410f by Ben Gamari at 2020-01-08T06:17:09-05:00 Bump haskeline submodule to 0.8.0.1 (cherry picked from commit feb3b955402d53c3875dd7a9a39f322827e5bd69) - - - - - 923a1272 by Ryan Scott at 2020-01-08T06:17:47-05:00 Print Core type applications with no whitespace after @ (#17643) This brings the pretty-printer for Core in line with how visible type applications are normally printed: namely, with no whitespace after the `@` character (i.e., `f @a` instead of `f @ a`). While I'm in town, I also give the same treatment to type abstractions (i.e., `\(@a)` instead of `\(@ a)`) and coercion applications (i.e., `f @~x` instead of `f @~ x`). Fixes #17643. - - - - - 49f83a0d by Adam Sandberg Eriksson at 2020-01-12T21:28:09-05:00 improve docs for HeaderInfo.getImports [skip ci] - - - - - 9129210f by Matthew Pickering at 2020-01-12T21:28:47-05:00 Overloaded Quotation Brackets (#246) This patch implements overloaded quotation brackets which generalise the desugaring of all quotation forms in terms of a new minimal interface. The main change is that a quotation, for example, [e| 5 |], will now have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass contains a single method for generating new names which is used when desugaring binding structures. The return type of functions from the `Lift` type class, `lift` and `liftTyped` have been restricted to `forall m . Quote m => m Exp` rather than returning a result in a Q monad. More details about the feature can be read in the GHC proposal. https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst - - - - - 350e2b78 by Richard Eisenberg at 2020-01-12T21:29:27-05:00 Don't zap to Any; error instead This changes GHC's treatment of so-called Naughty Quantification Candidates to issue errors, instead of zapping to Any. Close #16775. No new test cases, because existing ones cover this well. - - - - - 0b5ddc7f by Brian Wignall at 2020-01-12T21:30:08-05:00 Fix more typos, via an improved Levenshtein-style corrector - - - - - f732dbec by Ben Gamari at 2020-01-12T21:30:49-05:00 gitlab-ci: Retain bindists used by head.hackage for longer Previously we would keep them for two weeks. However, on the stable branches two weeks can easily elapse with no pushes. - - - - - c8636da5 by Sylvain Henry at 2020-01-12T21:31:30-05:00 Fix LANG=C for readelf invocation in T14999 The test fails when used with LANG=fr_FR.UTF-8 - - - - - 077a88de by Jean-Baptiste Mazon at 2020-01-12T21:32:08-05:00 users-guide/debug-info: typo “behivior” - - - - - 61916c5d by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Add comments about TH levels - - - - - 1fd766ca by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Comments about constraint floating - - - - - de01427e by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Minor refactor around quantified constraints This patch clarifies a dark corner of quantified constraints. * See Note [Yukky eq_sel for a HoleDest] in TcSMonad * Minor refactor, breaking out new function TcInteract.doTopReactEqPred - - - - - 30be3bf1 by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Comments in TcHsType - - - - - c5977d4d by Sebastian Graf at 2020-01-16T05:58:58-05:00 Better documentation for mkEtaWW [skip ci] So that hopefully I understand it faster next time. Also got rid of the confusing `orig_expr`, which makes the call site in `etaExpand` look out of sync with the passed `n` (which is not the original `n`). - - - - - 22c0bdc3 by John Ericson at 2020-01-16T05:59:37-05:00 Handle TagToEnum in the same big case as the other primops Before, it was a panic because it was handled above. But there must have been an error in my reasoning (another caller?) because #17442 reported the panic was hit. But, rather than figuring out what happened, I can just make it impossible by construction. By adding just a bit more bureaucracy in the return types, I can handle TagToEnum in the same case as all the others, so the big case is is now total, and the panic is removed. Fixes #17442 - - - - - ee5d63f4 by John Ericson at 2020-01-16T05:59:37-05:00 Get rid of OpDest `OpDest` was basically a defunctionalization. Just turn the code that cased on it into those functions, and call them directly. - - - - - 1ff55226 by John Ericson at 2020-01-16T06:00:16-05:00 Remove special case case of bool during STG -> C-- Allow removing the no longer needed cgPrimOp, getting rid of a small a small layer violation too. Change which made the special case no longer needed was #6135 / 6579a6c73082387f82b994305011f011d9d8382b, which dates back to 2013, making me feel better. - - - - - f416fe64 by Adam Wespiser at 2020-01-16T06:00:53-05:00 replace dead html link (fixes #17661) - - - - - f6bf2ce8 by Sebastian Graf at 2020-01-16T06:01:32-05:00 Revert "`exprOkForSpeculation` for Note [IO hack in the demand analyser]" This reverts commit ce64b397777408731c6dd3f5c55ea8415f9f565b on the grounds of the regression it would introduce in a couple of packages. Fixes #17653. Also undoes a slight metric increase in #13701 introduced by that commit that we didn't see prior to !1983. Metric Decrease: T13701 - - - - - a71323ff by Ben Gamari at 2020-01-17T08:43:16-05:00 gitlab-ci: Don't FORCE_SYMLINKS on Windows Not all runners have symlink permissions enabled. - - - - - 0499e3bc by Ömer Sinan Ağacan at 2020-01-20T15:31:33-05:00 Fix +RTS -Z flag documentation Stack squeezing is done on context switch, not on GC or stack overflow. Fix the documentation. Fixes #17685 [ci skip] - - - - - a661df91 by Ömer Sinan Ağacan at 2020-01-20T15:32:13-05:00 Document Stg.FVs module Fixes #17662 [ci skip] - - - - - db24e480 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Don't trash STG registers Fixes #13904. - - - - - f3d7fdb3 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix typo in readnone attribute - - - - - 442751c6 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Add lower-expect to the -O0 optimisation set @kavon says that this will improve block layout for stack checks. - - - - - e90ecc93 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix #14251 Fixes the calling convention for functions passing raw SSE-register values by adding padding as needed to get the values in the right registers. This problem cropped up when some args were unused an dropped from the live list. This folds together 2e23e1c7de01c92b038e55ce53d11bf9db993dd4 and 73273be476a8cc6c13368660b042b3b0614fd928 previously from @kavon. Metric Increase: T12707 ManyConstructors - - - - - 66e511a4 by Ben Gamari at 2020-01-20T15:33:28-05:00 testsuite: Preserve more information in framework failures Namely print the entire exception in hopes that this will help track down #17649. - - - - - b62b8cea by Ömer Sinan Ağacan at 2020-01-20T15:34:06-05:00 Remove deprecated -smp flag It was deprecated in 2012 with 46258b40 - - - - - 0c04a86a by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Reenable submodule linter - - - - - 2bfabd22 by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Allow submodule cleaning to fail on Windows Currently CI is inexplicably failing with ``` $ git submodule foreach git clean -xdf fatal: not a git repository: libffi-tarballs/../.git/modules/libffi-tarballs ``` I have no idea how this working tree got into such a state but we do need to fail more gracefully when it happens. Consequently, we allow the cleaning step to fail. - - - - - 14bced99 by Xavier Denis at 2020-01-20T15:35:21-05:00 Put the docs for :instances in alphabetical position - - - - - 7e0bb82b by Ben Gamari at 2020-01-20T15:35:57-05:00 Add missing Note [Improvement from Ground Wanteds] Closes #17659. - - - - - 17e43a7c by Ben Gamari at 2020-01-20T15:36:32-05:00 unregisterised: Fix declaration for stg_NO_FINALIZER Previously it had a redundant _entry suffix. We never noticed this previously presumably because we never generated references to it (however hard to believe this may be). However, it did start failing in !1304. - - - - - 3dae006f by PHO at 2020-01-20T15:37:08-05:00 Avoid ./configure failure on NetBSD - - - - - 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 49b4dc92 by Ben Gamari at 2020-04-13T11:42:23-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 714e6dd1 by Ben Gamari at 2020-04-13T11:47:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - 29 changed files: - − .circleci/config.yml - − .circleci/fetch-submodules.sh - − .circleci/prepare-system.sh - − .circleci/push-test-metrics.sh - .ghcid - .gitignore - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - − .gitlab/fix-submodules.py - .gitlab/issue_templates/bug.md - + .gitlab/issue_templates/documentation_issue.md - .gitlab/issue_templates/feature_request.md - + .gitlab/linters/check-changelogs.sh - .gitlab/linters/check-cpp.py - .gitlab/linters/check-makefiles.py - .gitlab/linters/linter.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/push-test-metrics.sh - .gitlab/start-head.hackage.sh - + .gitlab/test-metrics.sh - − .gitlab/win32-init.sh - .gitmodules - .mailmap - CODEOWNERS - HACKING.md - aclocal.m4 - boot - − build.nix.sh The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7a32d1a197839380fd8fdb0567ce765135b7ac4...714e6dd156f940e5710be4a003b42d58b22cf2bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7a32d1a197839380fd8fdb0567ce765135b7ac4...714e6dd156f940e5710be4a003b42d58b22cf2bb You're receiving 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 13 17:57:12 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 13 Apr 2020 13:57:12 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5e94a7f8ae8d7_61673f81ef22dee44732198@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: 21555e06 by Andreas Klebinger at 2020-04-13T19:32:44+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation. * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 11 changed files: - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs - compiler/GHC/CmmToAsm/Reg/Linear/State.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs - compiler/utils/Outputable.hs Changes: ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -636,22 +636,8 @@ sequenceChain :: forall a i. (Instruction i, Outputable i) -> [GenBasicBlock i] -- ^ Blocks placed in sequence. sequenceChain _info _weights [] = [] sequenceChain _info _weights [x] = [x] -sequenceChain info weights' blocks@((BasicBlock entry _):_) = - let weights :: CFG - weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' - where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights - - directEdges :: [CfgEdge] +sequenceChain info weights blocks@((BasicBlock entry _):_) = + let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where relevantWeight :: CfgEdge -> Maybe CfgEdge ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,20 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG weights proc@(CmmProc _info _lab _live graph) cfg = + staticPredCfg (g_entry graph) . optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +758,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +946,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,12 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +252,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +287,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +331,21 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + + -- assig <- getBlockAssigR + -- pprTraceM "assignment" $ ppr assig + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +381,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +408,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are love on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> BlockId -- ^ the id of the current block, for debugging @@ -476,7 +488,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +498,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,10 +538,12 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. - -- when (not $ null fixup_blocks) $ - -- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) +-- when (not $ null fixup_blocks) $ +-- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) -- (e) Delete all register assignments for temps which are read -- (only) and die here. Update the free register list. @@ -737,7 +752,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +764,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +795,19 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a (potential empty) list of preferred real registers. +findPrefRealRegs :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs ([RealReg]) +findPrefRealRegs vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) [] bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> [RealReg] -> [RealReg] + findVirtRegAssig assig z = + case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> real_reg : z + Just (InBoth real_reg _) -> real_reg : z + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,10 +824,14 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + pref_regs <- findPrefRealRegs r + -- TODO: Intersect is O(n²), it might be better to construct sets first. + -- But the lists involved are quite small so for now lists will do. + let pref_free_regs = intersect pref_regs freeRegs_thisClass + case pref_free_regs <|> freeRegs_thisClass of -- case (2): we have a free register (my_reg : _) -> do spills' <- loadTemp r spill_loc my_reg spills @@ -814,7 +847,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,9 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + -- | Map virtual regs to regs they have been assigned in the past. + , ra_sugg_assig :: RegMap Loc } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} @@ -111,7 +112,8 @@ runR config block_assig freeregs assig stack us thing = , ra_us = us , ra_spills = [] , ra_config = config - , ra_fixups = [] }) + , ra_fixups = [] + , ra_sugg_assig = assig }) of RA_Result state returned_thing -> (ra_blockassig state, ra_stack state, makeRAStats state, returned_thing) ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/utils/Outputable.hs ===================================== @@ -847,6 +847,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21555e062b2d2cbcde8483cf1361a4ae06e6f956 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21555e062b2d2cbcde8483cf1361a4ae06e6f956 You're receiving 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 13 18:06:28 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 13 Apr 2020 14:06:28 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] 38 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5e94aa24929cd_6167136dfb9c47366a2@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - ec44e160 by Andreas Klebinger at 2020-04-13T15:54:53+02:00 Rework treatment of `elem`. Add UTF8 GHC.CString functions. A fusion RULE for elem was broken preventing it from firing. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. This now also works for unboxed string literals via a builtin rule. As a byproduct GHC.CString functionality is now available for Ascii and UTF8 strings. The following missing UTF8 variants were added: unpackAppendCStringUtf8#, unpackFoldrCStringUtf8# They work just like their ascii counterparts. Which hopefully makes proper UTF8 support easier for library authors and was required to support this transformation for utf8 encoded unboxed strings. - - - - - e0c0b917 by Andreas Klebinger at 2020-04-13T15:54:55+02:00 Update comments/notes - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15ca17aa375a9460c95d31151c8ca0388b8f037b...e0c0b91715667bbd0b3305d2424f4edd6e5000a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15ca17aa375a9460c95d31151c8ca0388b8f037b...e0c0b91715667bbd0b3305d2424f4edd6e5000a0 You're receiving 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 13 20:31:53 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 13 Apr 2020 16:31:53 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18052 Message-ID: <5e94cc39b2e69_61673f81ef22dee44774913@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18052 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18052 You're receiving 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 13 20:34:12 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 13 Apr 2020 16:34:12 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Significant refactor of Lint Message-ID: <5e94ccc48f64_61673f8199536d9447799ba@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 49ea4c01 by Krzysztof Gogolewski at 2020-04-13T16:33:56-04:00 Change zipWith to zipWithEqual in a few places - - - - - 73818ece by Andreas Klebinger at 2020-04-13T16:33:57-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - d27af927 by Alp Mestanogullari at 2020-04-13T16:34:01-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - 16928cb1 by Julien Debon at 2020-04-13T16:34:03-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 30 changed files: - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/utils/Binary.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/extending_ghc.rst - docs/users_guide/exts/existential_quantification.rst - + docs/users_guide/exts/field_selectors_and_type_applications.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/rank_polymorphism.rst - docs/users_guide/exts/records.rst - hadrian/src/Builder.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4e78b76569e2247cfbe00264990268e6d99b1ab5...16928cb1f2933f082aa17a3d9042216b8a5e5726 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4e78b76569e2247cfbe00264990268e6d99b1ab5...16928cb1f2933f082aa17a3d9042216b8a5e5726 You're receiving 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 13 21:12:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 17:12:33 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5e94d5c1ee361_61673f8199536d944794856@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: 16570e42 by Ben Gamari at 2020-04-13T17:12:20-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 10 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +flushEventLog :: IO () +flushEventLog = c_flushEventLog nullPtr + +foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO () ===================================== rts/Capability.c ===================================== @@ -23,6 +23,7 @@ #include "Schedule.h" #include "Sparks.h" #include "Trace.h" +#include "eventlog/EventLog.h" // for flushLocalEventsBuf #include "sm/GC.h" // for gcWorkerThread() #include "STM.h" #include "RtsUtils.h" @@ -885,6 +886,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushTrace(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/Trace.h ===================================== @@ -319,7 +319,6 @@ void traceConcSweepEnd(void); void traceConcUpdRemSetFlush(Capability *cap); void traceNonmovingHeapCensus(uint32_t log_blk_size, const struct NonmovingAllocCensus *census); - void flushTrace(void); #else /* !TRACING */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -16,6 +16,7 @@ #include "RtsUtils.h" #include "Stats.h" #include "EventLog.h" +#include "Schedule.h" #include #include @@ -271,7 +272,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1566,26 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = myTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) @@ -1578,4 +1599,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { void endEventLogging(void) {} +void flushEventLog(Capability **cap STG_UNUSED) {} + #endif /* TRACING */ ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,10 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event @@ -175,6 +177,9 @@ void postNonmovingHeapCensus(int log_blk_size, #else /* !TRACING */ +INLINE_HEADER void flushLocalEventsBuf(Capability *cap) +{ /* nothing */ } + INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, EventTypeNum tag STG_UNUSED, StgThreadID id STG_UNUSED, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16570e421589aeb2a619b9c9ab472caa05289231 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16570e421589aeb2a619b9c9ab472caa05289231 You're receiving 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 13 21:17:09 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 17:17:09 -0400 Subject: [Git][ghc/ghc][wip/T17944] 83 commits: Fix ApplicativeDo regression #17835 Message-ID: <5e94d6d595e66_6167134ebbc448019ec@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17944 at Glasgow Haskell Compiler / GHC Commits: 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - fc8e28d1 by Ben Gamari at 2020-04-13T17:17:04-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 30 changed files: - .gitlab-ci.yml - CODEOWNERS - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Cmm/Sink.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c39d7659dd36633a460503dc6c3984cac0a4028...fc8e28d1e70e5ce9ca6aecddea966bd922a030c8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c39d7659dd36633a460503dc6c3984cac0a4028...fc8e28d1e70e5ce9ca6aecddea966bd922a030c8 You're receiving 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 13 21:57:35 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 17:57:35 -0400 Subject: [Git][ghc/ghc][wip/backports] 9 commits: Force -fPIC for intree GMP (fix #17799) Message-ID: <5e94e04f96118_61673f8198ee100c481105@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 07c0d148 by Sylvain Henry at 2020-04-13T17:57:19-04:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). (cherry picked from commit e1e329448f3742b2024ca6bc2c78f36fe282b606) - - - - - 64fb49c9 by Ben Gamari at 2020-04-13T17:57:19-04:00 gitlab-ci: Add FreeBSD release job - - - - - d1464459 by Ben Gamari at 2020-04-13T17:57:19-04:00 Mention -Wunused-packages in release notes - - - - - 9ba0cd3e by Ben Gamari at 2020-04-13T17:57:19-04:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. (cherry picked from commit e5ee07ab565c1bf7a33d3bd4bcd3fb6c7b100d1c) - - - - - c0b4e2cc by Ben Gamari at 2020-04-13T17:57:19-04:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 2daee665 by Ben Gamari at 2020-04-13T17:57:19-04:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 12bb9912 by Ben Gamari at 2020-04-13T17:57:20-04:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 3717c610 by Ben Gamari at 2020-04-13T17:57:20-04:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 9ff90fd8 by Ben Gamari at 2020-04-13T17:57:20-04:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - 12 changed files: - .gitlab-ci.yml - compiler/main/DynFlags.hs - configure.ac - docs/users_guide/8.10.1-notes.rst - hadrian/src/Settings/Builders/Configure.hs - libraries/base/GHC/IO/FD.hs - libraries/integer-gmp/gmp/ghc.mk - libraries/integer-gmp/gmp/gmpsrc.patch - testsuite/tests/cmm/should_compile/Makefile - testsuite/tests/cmm/should_compile/T16930.stdout - testsuite/tests/driver/T16608/Makefile - testsuite/tests/runghc/all.T Changes: ===================================== .gitlab-ci.yml ===================================== @@ -344,6 +344,11 @@ nightly-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build +release-x86_64-freebsd: + <<: *release + extends: .build-x86_64-freebsd + stage: full-build + .build-x86_64-freebsd-hadrian: extends: .validate-hadrian stage: full-build ===================================== compiler/main/DynFlags.hs ===================================== @@ -1817,7 +1817,9 @@ wayOptl :: Platform -> Way -> [String] wayOptl _ (WayCustom {}) = [] wayOptl platform WayThreaded = case platformOS platform of - OSFreeBSD -> ["-pthread"] + -- N.B. FreeBSD cc throws a warning if we pass -pthread without + -- actually using any pthread symbols. + OSFreeBSD -> ["-pthread", "-Wno-unused-command-line-argument"] OSOpenBSD -> ["-pthread"] OSNetBSD -> ["-pthread"] _ -> [] ===================================== configure.ac ===================================== @@ -836,7 +836,7 @@ AC_PATH_PROG(SPHINXBUILD,sphinx-build) AC_CACHE_CHECK([for version of sphinx-build], fp_cv_sphinx_version, changequote(, )dnl [if test -n "$SPHINXBUILD"; then - fp_cv_sphinx_version=`"$SPHINXBUILD" --version 2>&1 | sed 's/.* v\?\([0-9]\.[0-9]\.[0-9]\)/\1/' | head -n1`; + fp_cv_sphinx_version=`"$SPHINXBUILD" --version 2>&1 | sed 's/.* \([0-9]\.[0-9]\.[0-9]\)/\1/' | head -n1`; fi; changequote([, ])dnl ]) ===================================== docs/users_guide/8.10.1-notes.rst ===================================== @@ -187,6 +187,8 @@ Compiler has been removed. From this point forth GHC will only support floating point via SSE2. +- New :ghc-flag:`-Wunused-packages` warning reports unused packages. + - Add new flags :ghc-flag:`-Wunused-record-wildcards` and :ghc-flag:`-Wredundant-record-wildcards` which warn users when they have redundant or unused uses of a record wildcard match. ===================================== hadrian/src/Settings/Builders/Configure.hs ===================================== @@ -13,6 +13,7 @@ configureBuilderArgs = do hostPlatform <- getSetting HostPlatform buildPlatform <- getSetting BuildPlatform pure [ "--enable-shared=no" + , "--with-pic=yes" , "--host=" ++ hostPlatform , "--build=" ++ buildPlatform ] ===================================== libraries/base/GHC/IO/FD.hs ===================================== @@ -67,16 +67,13 @@ import System.Posix.Types c_DEBUG_DUMP :: Bool c_DEBUG_DUMP = False --- Darwin limits the length of writes to 2GB. See --- #17414. +-- Darwin limits the length of writes to 2GB. See #17414. +-- Moreover, Linux will only transfer up to 0x7ffff000 and interpreting the +-- result of write/read is tricky above 2GB due to its signed type. For +-- simplicity we therefore clamp on all platforms. clampWriteSize, clampReadSize :: Int -> Int -#if defined(darwin_HOST_OS) -clampWriteSize = min 0x7fffffff -clampReadSize = min 0x7fffffff -#else -clampWriteSize = id -clampReadSize = id -#endif +clampWriteSize = min 0x7ffff000 +clampReadSize = min 0x7ffff000 -- ----------------------------------------------------------------------------- -- The file-descriptor IO device ===================================== libraries/integer-gmp/gmp/ghc.mk ===================================== @@ -131,7 +131,7 @@ libraries/integer-gmp/gmp/libgmp.a libraries/integer-gmp/gmp/gmp.h: # run is the 'target' platform of the compiler we're building. cd libraries/integer-gmp/gmp/gmpbuild; \ CC=$(CCX) CXX=$(CCX) NM=$(NM) AR=$(AR_STAGE1) ./configure \ - --enable-shared=no \ + --enable-shared=no --with-pic=yes \ --host=$(TARGETPLATFORM) --build=$(BUILDPLATFORM) $(MAKE) -C libraries/integer-gmp/gmp/gmpbuild MAKEFLAGS= $(CP) libraries/integer-gmp/gmp/gmpbuild/gmp.h libraries/integer-gmp/gmp/ ===================================== libraries/integer-gmp/gmp/gmpsrc.patch ===================================== @@ -1,27 +1,6 @@ diff -Naur gmp-6.1.2/configure gmpbuild/configure --- gmp-6.1.2/configure 2016-12-16 10:45:32.000000000 -0500 +++ gmpbuild/configure 2017-01-29 15:18:01.037775639 -0500 -@@ -4087,8 +4087,8 @@ - # - cclist="gcc cc" - --gcc_cflags="-O2 -pedantic" --gcc_64_cflags="-O2 -pedantic" -+gcc_cflags="-O2 -pedantic -fPIC" -+gcc_64_cflags="-O2 -pedantic -fPIC" - cc_cflags="-O" - cc_64_cflags="-O" - -@@ -27273,6 +27273,9 @@ - case $host in - *-*-darwin*) - -+echo "define(,)" >> $gmp_tmpconfigm4 -+ -+ - echo "include_mpn(\`x86_64/darwin.m4')" >> $gmp_tmpconfigm4i - ;; - *-*-mingw* | *-*-cygwin) @@ -28181,7 +28181,7 @@ # FIXME: Upcoming version of autoconf/automake may not like broken lines. # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. @@ -63,27 +42,3 @@ diff -Naur gmp-6.1.2/Makefile.in gmpbuild/Makefile.in # The "test -f" support for srcdir!=builddir is similar to the automake .c.o # etc rules, but with each foo.c explicitly, since $< is not portable -diff -Naur gmp-6.1.2/configure.ac gmpbuild/configure.ac ---- gmp-6.1.2/configure.ac 2016-12-16 10:45:27.000000000 -0500 -+++ gmpbuild/configure.ac 2017-01-29 22:47:28.469558006 -0500 -@@ -3698,7 +3698,8 @@ - AC_DEFINE(HAVE_HOST_CPU_FAMILY_x86_64) - case $host in - *-*-darwin*) -+ GMP_DEFINE_RAW(["define(,)"]) - GMP_INCLUDE_MPN(x86_64/darwin.m4) ;; - *-*-mingw* | *-*-cygwin) - GMP_INCLUDE_MPN(x86_64/dos64.m4) ;; - *-openbsd*) -diff -Naur gmp-6.1.2/mpn/asm-defs.m4 gmpbuild/mpn/asm-defs.m4 ---- gmp-6.1.2/mpn/asm-defs.m4 2016-12-16 10:45:27.000000000 -0500 -+++ gmpbuild/mpn/asm-defs.m4 2017-01-29 22:46:26.025176258 -0500 -@@ -1051,7 +1051,7 @@ - dnl systems which are always PIC. PIC_ALWAYS established in config.m4 - dnl identifies these for us. - --ifelse(`PIC_ALWAYS',`yes',`define(`PIC')') -+ifelse(PIC_ALWAYS,yes,`define(`PIC')') - - - dnl Various possible defines passed from the Makefile that are to be tested ===================================== testsuite/tests/cmm/should_compile/Makefile ===================================== @@ -7,9 +7,9 @@ include $(TOP)/mk/test.mk T16930: echo "testing -ddump-cmm-verbose for T16930 ..." '$(TEST_HC)' $(TEST_HC_OPTS) T16930.hs -fforce-recomp -ddump-cmm-verbose -ddump-to-file - grep -rl "CAFEnv" . --include=\T16930.* - grep -rl "Post control-flow optimisations" . --include=\T16930.* - grep -rl "Post CPS Cmm" . --include=\T16930.* - grep -rl "after setInfoTableStackMap" . --include=\T16930.* - grep -rl "Layout Stack" . --include=\T16930.* - grep -rl "Post switch plan" . --include=\T16930.* + grep -rl "CAFEnv" `ls T16930.*` + grep -rl "Post control-flow optimisations" `ls T16930.*` + grep -rl "Post CPS Cmm" `ls T16930.*` + grep -rl "after setInfoTableStackMap" `ls T16930.*` + grep -rl "Layout Stack" `ls T16930.*` + grep -rl "Post switch plan" `ls T16930.*` ===================================== testsuite/tests/cmm/should_compile/T16930.stdout ===================================== @@ -1,9 +1,9 @@ testing -ddump-cmm-verbose for T16930 ... [1 of 1] Compiling Main ( T16930.hs, T16930.o ) Linking T16930 ... -./T16930.dump-cmm-caf -./T16930.dump-cmm-cfg -./T16930.dump-cmm-cps -./T16930.dump-cmm-info -./T16930.dump-cmm-sp -./T16930.dump-cmm-switch +T16930.dump-cmm-caf +T16930.dump-cmm-cfg +T16930.dump-cmm-cps +T16930.dump-cmm-info +T16930.dump-cmm-sp +T16930.dump-cmm-switch ===================================== testsuite/tests/driver/T16608/Makefile ===================================== @@ -3,6 +3,8 @@ include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk T16608_1: + # FreeBSD's sed doesn't like operating in-place on symlinks. Un-symlinkify. + mv MyInteger.hs tmp.hs; cp tmp.hs MyInteger.hs '$(TEST_HC)' $(TEST_HC_OPTS) --make -O0 T16608_1.hs ./T16608_1 sleep 1 @@ -11,6 +13,8 @@ T16608_1: ./T16608_1 T16608_2: + # FreeBSD's sed doesn't like operating in-place on symlinks. Un-symlinkify. + mv MyInteger.hs tmp.hs; cp tmp.hs MyInteger.hs '$(TEST_HC)' $(TEST_HC_OPTS) --make -O0 T16608_2.hs ./T16608_2 sleep 1 ===================================== testsuite/tests/runghc/all.T ===================================== @@ -4,7 +4,9 @@ test('T8601', req_interp, makefile_test, []) test('T11247', [req_interp, expect_broken(11247)], makefile_test, []) -test('T6132', [when(opsys('darwin'), expect_broken(6132))], compile, ['']) +test('T6132', [ + when(opsys('darwin') or opsys('freebsd'), expect_broken(6132))], + compile, ['']) test('T17171a', [req_interp, expect_fail], makefile_test, []) test('T17171b', req_interp, makefile_test, []) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2aee0fe0b47def25a1c4ba393b9f84fb820de0e6...9ff90fd85e2c611a97ba36357ec50972d32db850 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2aee0fe0b47def25a1c4ba393b9f84fb820de0e6...9ff90fd85e2c611a97ba36357ec50972d32db850 You're receiving 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 13 23:22:53 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 13 Apr 2020 19:22:53 -0400 Subject: [Git][ghc/ghc][wip/T17775] 25 commits: hadrian: Use --export-dynamic when linking iserv Message-ID: <5e94f44d733ed_616776d1c74481705@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - b7a20bc0 by Simon Peyton Jones at 2020-04-14T00:22:09+01:00 Simplify subsumption This patch implements GHC Proposal 287: Simplify subsumption and ticket #17775. The highlights are: * No deeplyInstantiate or deeplySkolemise * No tcSubTypeDS Everything else is a knock-on effect. I did a bit of renaming to make things consistent * tcPolyExpr becomes tcCheckPolyExpr ditto tcPolyExprNC * Add new function tcCheckMonoExpr e ty = tcMon0Expr expr (mkCheckExpType ty) and use it This all comopiles, but needs some eta-expansion in haskeline, and doubtless other packages. - - - - - a340ad17 by Simon Peyton Jones at 2020-04-14T00:22:10+01:00 Further refactoring and simplification Reviewed the main changes with Richard I had to do eta-expansion in a number of tests: T10283 T10390 T14488 T1634 T4284 T9569a T9834 tc145 tc160 tc208 tc210 twins - - - - - 1aea80c6 by Ben Gamari at 2020-04-14T00:22:10+01:00 Bump haskeline submodule - - - - - 1967c0a8 by Simon Peyton Jones at 2020-04-14T00:22:10+01:00 Delete commented-out code - - - - - 06c2ec3e by Simon Peyton Jones at 2020-04-14T00:22:10+01:00 Fix (breaking) typo - - - - - 50135ff4 by Simon Peyton Jones at 2020-04-14T00:22:11+01:00 Improve decomposition for FunTys This just improves error messages, avoiding Couldn't match type ‘Char’ with ‘Show a -> Char’ - - - - - ceb8055a by Ryan Scott at 2020-04-14T00:22:11+01:00 Bump Cabal submodule As well as some miscellaneous fixes needed to make GHC itself compile under simplified subsumption. - - - - - 2772cb51 by Simon Peyton Jones at 2020-04-14T00:22:11+01:00 Wibbles * Get expected/actual the right way round * Relevant-bindings fixes - - - - - aacec564 by Simon Peyton Jones at 2020-04-14T00:22:12+01:00 A lot more wibbles * Made String wired-in, so that "foo" :: String rather than "foo" :: [Char] * isTauTy: account for => * Bring dicts into scope when desugaring HsWrappers: addTyCsDs and hsWrapDictBinders * Improve reporting for occurs checks where skolems are involved e.g. 10715b, mc19, tcfail193, T13674, T4272, T3169, T7758, 7148 Payload is in the first case of mkTyVarEqErr * solveLocalEqualitesX: fail faster. we want to fail fast in T11142 Another example: T15629 And keep all equalities in dropMisleading. This gives better reporting in T12593 for example. * Move checkDataKindSig after the solveEqualities and zonk, obviously! * Move ic_telescope into ForAllSkol; a nice win. * Pretty-printing AbsBinds We are now very close to green - - - - - 30 changed files: - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d52887dc1e9f66fa8f48cd4d4817f8480f091f9...aacec56452dfc96a943817e1be76a082a4f222bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d52887dc1e9f66fa8f48cd4d4817f8480f091f9...aacec56452dfc96a943817e1be76a082a4f222bb You're receiving 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 13 23:29:06 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 13 Apr 2020 19:29:06 -0400 Subject: [Git][ghc/ghc][wip/T17173] Major refactor of typechecking applications Message-ID: <5e94f5c223bf6_6167136dfb9c48198db@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: f39a0d86 by Simon Peyton Jones at 2020-04-14T00:26:04+01:00 Major refactor of typechecking applications Following conversation with Richard today, I have done major surgery on tcApp and friends. Fewer arguments, less plumbing, all good. I also completely killed off ir_inst. It's not as well documented as I want, yet, but I'm pushing it up for Richard's review. (This message will be replaced with a proper commit message.) - - - - - 24 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Zonk.hs - testsuite/tests/typecheck/should_fail/tcfail007.stderr - testsuite/tests/typecheck/should_fail/tcfail010.stderr - testsuite/tests/typecheck/should_fail/tcfail029.stderr - testsuite/tests/typecheck/should_fail/tcfail034.stderr - testsuite/tests/typecheck/should_fail/tcfail133.hs - testsuite/tests/typecheck/should_fail/tcfail143.stderr - testsuite/tests/typecheck/should_fail/tcfail208.stderr Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -599,7 +599,9 @@ type instance XLam (GhcPass _) = NoExtField type instance XLamCase (GhcPass _) = NoExtField type instance XApp (GhcPass _) = NoExtField -type instance XAppTypeE (GhcPass _) = NoExtField +type instance XAppTypeE GhcPs = NoExtField +type instance XAppTypeE GhcRn = NoExtField +type instance XAppTypeE GhcTc = Type type instance XOpApp GhcPs = NoExtField type instance XOpApp GhcRn = Fixity ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -185,8 +185,7 @@ mkLocatedList ms = L (combineLocs (head ms) (last ms)) ms mkHsApp :: LHsExpr (GhcPass id) -> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id) mkHsApp e1 e2 = addCLoc e1 e2 (HsApp noExtField e1 e2) -mkHsAppType :: (NoGhcTc (GhcPass id) ~ GhcRn) - => LHsExpr (GhcPass id) -> LHsWcType GhcRn -> LHsExpr (GhcPass id) +mkHsAppType :: LHsExpr GhcRn -> LHsWcType GhcRn -> LHsExpr GhcRn mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) where t_body = hswc_body t ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -319,9 +319,9 @@ dsExpr e@(HsApp _ fun arg) ; dsWhenNoErrs (dsLExprNoLP arg) (\arg' -> mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg') } -dsExpr (HsAppType _ e _) - -- ignore type arguments here; they're in the wrappers instead at this point - = dsLExpr e +dsExpr (HsAppType ty e _) + = do { e' <- dsLExpr e + ; return (App e' (mkTyArg ty)) } {- Note [Desugaring vars] ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -14,7 +14,7 @@ module GHC.Tc.Gen.Arrow ( tcProc ) where import GhcPrelude -import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcMonoExpr, tcInferRho, tcSyntaxOp, tcCheckId, tcPolyExpr ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcLExpr, tcInferRho, tcSyntaxOp, tcCheckId, tcPolyExpr ) import GHC.Hs import GHC.Tc.Gen.Match @@ -161,7 +161,7 @@ tc_cmd env in_cmd@(HsCmdCase x scrut matches) (stk, res_ty) ; tcCmd env body (stk, res_ty') } tc_cmd env (HsCmdIf x NoSyntaxExprRn pred b1 b2) res_ty -- Ordinary 'if' - = do { pred' <- tcMonoExpr pred (mkCheckExpType boolTy) + = do { pred' <- tcLExpr pred (mkCheckExpType boolTy) ; b1' <- tcCmd env b1 res_ty ; b2' <- tcCmd env b2 res_ty ; return (HsCmdIf x NoSyntaxExprTc pred' b1' b2') @@ -179,7 +179,7 @@ tc_cmd env (HsCmdIf x fun@(SyntaxExprRn {}) pred b1 b2) res_ty -- Rebindable syn ; (pred', fun') <- tcSyntaxOp IfOrigin fun (map synKnownType [pred_ty, r_ty, r_ty]) (mkCheckExpType r_ty) $ \ _ -> - tcMonoExpr pred (mkCheckExpType pred_ty) + tcLExpr pred (mkCheckExpType pred_ty) ; b1' <- tcCmd env b1 res_ty ; b2' <- tcCmd env b2 res_ty @@ -206,9 +206,9 @@ tc_cmd env cmd@(HsCmdArrApp _ fun arg ho_app lr) (_, res_ty) = addErrCtxt (cmdCtxt cmd) $ do { arg_ty <- newOpenFlexiTyVarTy ; let fun_ty = mkCmdArrTy env arg_ty res_ty - ; fun' <- select_arrow_scope (tcMonoExpr fun (mkCheckExpType fun_ty)) + ; fun' <- select_arrow_scope (tcLExpr fun (mkCheckExpType fun_ty)) - ; arg' <- tcMonoExpr arg (mkCheckExpType arg_ty) + ; arg' <- tcLExpr arg (mkCheckExpType arg_ty) ; return (HsCmdArrApp fun_ty fun' arg' ho_app lr) } where @@ -233,7 +233,7 @@ tc_cmd env cmd@(HsCmdApp x fun arg) (cmd_stk, res_ty) = addErrCtxt (cmdCtxt cmd) $ do { arg_ty <- newOpenFlexiTyVarTy ; fun' <- tcCmd env fun (mkPairTy arg_ty cmd_stk, res_ty) - ; arg' <- tcMonoExpr arg (mkCheckExpType arg_ty) + ; arg' <- tcLExpr arg (mkCheckExpType arg_ty) ; return (HsCmdApp x fun' arg') } ------------------------------------------- ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -23,7 +23,7 @@ where import GhcPrelude import {-# SOURCE #-} GHC.Tc.Gen.Match ( tcGRHSsPat, tcMatchesFun ) -import {-# SOURCE #-} GHC.Tc.Gen.Expr ( tcMonoExpr ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr ( tcLExpr ) import {-# SOURCE #-} GHC.Tc.TyCl.PatSyn ( tcPatSynDecl, tcPatSynBuilderBind ) import GHC.Core (Tickish (..)) import GHC.Types.CostCentre (mkUserCC, CCFlavour(DeclCC)) @@ -354,7 +354,7 @@ tcLocalBinds (HsIPBinds x (IPBinds _ ip_binds)) thing_inside = do { ty <- newOpenFlexiTyVarTy ; let p = mkStrLitTy $ hsIPNameFS ip ; ip_id <- newDict ipClass [ p, ty ] - ; expr' <- tcMonoExpr expr (mkCheckExpType ty) + ; expr' <- tcLExpr expr (mkCheckExpType ty) ; let d = toDict ipClass p ty `fmap` expr' ; return (ip_id, (IPBind noExtField (Right ip_id) d)) } tc_ip_bind _ (IPBind _ (Right {}) _) = panic "tc_ip_bind" @@ -1267,9 +1267,7 @@ tcMonoBinds is_rec sig_fn no_gen -- We want to infer a higher-rank type for f setSrcSpan b_loc $ do { ((co_fn, matches'), rhs_ty) - <- tcInferInst $ \ exp_ty -> - -- tcInferInst: see GHC.Tc.Utils.Unify, - -- Note [Deep instantiation of InferResult] in GHC.Tc.Utils.Unify + <- tcInfer $ \ exp_ty -> tcExtendBinderStack [TcIdBndr_ExpType name exp_ty NotTopLevel] $ -- We extend the error context even for a non-recursive -- function so that in type error messages we show the @@ -1366,7 +1364,7 @@ tcLhs sig_fn no_gen (PatBind { pat_lhs = pat, pat_rhs = grhss }) -- See Note [Existentials in pattern bindings] ; ((pat', nosig_mbis), pat_ty) <- addErrCtxt (patMonoBindsCtxt pat grhss) $ - tcInferInst $ \ exp_ty -> -- The ir_inst field is irrelevant for patterns + tcInfer $ \ exp_ty -> tcLetPat inst_sig_fun no_gen pat exp_ty $ mapM lookup_info nosig_names ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -7,20 +7,21 @@ {-# LANGUAGE CPP, TupleSections, ScopedTypeVariables #-} {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilies, DataKinds, TypeApplications #-} +{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] + -- in module GHC.Hs.Extension {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | Typecheck an expression module GHC.Tc.Gen.Expr ( tcPolyExpr - , tcMonoExpr, tcMonoExprNC - , tcInferRho, tcInferRhoNC, tcInferAppHead + , tcLExpr, tcLExprNC, tcExpr + , tcInferRho, tcInferRhoNC, tcInferApp , tcSyntaxOp, tcSyntaxOpGen , SyntaxOpType(..) , synKnownType , tcCheckId - , addExprErrCtxt , addAmbiguousNameErr , getFixedTyVars ) @@ -43,7 +44,7 @@ import GHC.Tc.Utils.Instantiate import GHC.Tc.Gen.Bind ( chooseInferredQuantifiers, tcLocalBinds ) import GHC.Tc.Gen.Sig ( tcUserTypeSig, tcInstSig ) import GHC.Tc.Solver ( simplifyInfer, InferMode(..) ) -import GHC.Tc.Instance.Family ( tcGetFamInstEnvs, tcLookupDataFamInst ) +import GHC.Tc.Instance.Family ( tcGetFamInstEnvs, tcLookupDataFamInst, tcLookupDataFamInst_maybe ) import GHC.Core.FamInstEnv ( FamInstEnvs ) import GHC.Rename.Env ( addUsedGRE ) import GHC.Rename.Utils ( addNameClashErrRn, unknownSubordinateErr ) @@ -73,7 +74,6 @@ import GHC.Core.Type import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import TysWiredIn -import TysPrim( intPrimTy ) import PrimOp( tagToEnumKey ) import PrelNames import GHC.Driver.Session @@ -104,7 +104,7 @@ import qualified Data.Set as Set tcPolyExpr, tcPolyExprNC :: LHsExpr GhcRn -- Expression to type check -> TcSigmaType -- Expected type (could be a polytype) - -> TcM (LHsExpr GhcTcId) -- Generalised expr with expected type + -> TcM (LHsExpr GhcTc) -- Generalised expr with expected type -- tcPolyExpr is a convenient place (frequent but not too frequent) -- place to add context information. @@ -116,9 +116,9 @@ tcPolyExprNC expr res_ty = tc_poly_expr_nc expr (mkCheckExpType res_ty) -- these versions take an ExpType tc_poly_expr, tc_poly_expr_nc :: LHsExpr GhcRn -> ExpSigmaType - -> TcM (LHsExpr GhcTcId) + -> TcM (LHsExpr GhcTc) tc_poly_expr expr res_ty - = addExprErrCtxt expr $ + = addErrCtxt (exprCtxt expr) $ do { traceTc "tcPolyExpr" (ppr res_ty); tc_poly_expr_nc expr res_ty } tc_poly_expr_nc (L loc expr) res_ty @@ -130,31 +130,22 @@ tc_poly_expr_nc (L loc expr) res_ty ; return $ L loc (mkHsWrap wrap expr') } --------------- -tcMonoExpr, tcMonoExprNC - :: LHsExpr GhcRn -- Expression to type check - -> ExpRhoType -- Expected type - -- Definitely no foralls at the top - -> TcM (LHsExpr GhcTcId) - -tcMonoExpr expr res_ty - = addErrCtxt (exprCtxt expr) $ - tcMonoExprNC expr res_ty - -tcMonoExprNC (L loc expr) res_ty - = setSrcSpan loc $ - do { expr' <- tcExpr expr res_ty - ; return (L loc expr') } - ---------------- -tcInferRho, tcInferRhoNC :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcRhoType) --- Infer a *rho*-type. The return type is always (shallowly) instantiated. -tcInferRho expr = addErrCtxt (exprCtxt expr) (tcInferRhoNC expr) +tcInferRho, tcInferRhoNC :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcRhoType) +-- Infer a *rho*-type. The return type is always instantiated. +-- Don't wrap in "In the expression Wrap in a context iff non-atom +tcInferRho le@(L _ e) + | isAtomicHsExpr e = tcInferRhoNC le + | otherwise = addErrCtxt (exprCtxt le) (tcInferRhoNC le) tcInferRhoNC (L loc expr) = setSrcSpan loc $ - do { (expr', rho) <- tcInferInst (tcExpr expr) + do { (expr', rho) <- tcInfer (tcExpr expr) ; return (L loc expr', rho) } +exprCtxt :: LHsExpr GhcRn -> SDoc +exprCtxt expr + = hang (text "In the expression:") 2 (ppr (stripParensHsExpr expr)) + {- ************************************************************************ * * @@ -165,29 +156,38 @@ tcInferRhoNC (L loc expr) NB: The res_ty is always deeply skolemised. -} -tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId) +tcLExpr, tcLExprNC + :: LHsExpr GhcRn -- Expression to type check + -> ExpRhoType -- Expected type + -- Definitely no foralls at the top + -> TcM (LHsExpr GhcTc) + +tcLExpr expr res_ty + = addErrCtxt (exprCtxt expr) $ + tcLExprNC expr res_ty + +tcLExprNC (L loc expr) res_ty + = setSrcSpan loc $ + do { expr' <- tcExpr expr res_ty + ; return (L loc expr') } + +tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) tcExpr (HsVar _ (L _ name)) res_ty = tcCheckId name res_ty tcExpr e@(HsUnboundVar _ uv) res_ty = tcUnboundId e uv res_ty -tcExpr e@(HsApp {}) res_ty = tcApp1 e res_ty -tcExpr e@(HsAppType {}) res_ty = tcApp1 e res_ty +tcExpr e@(HsApp {}) res_ty = tcApp e res_ty +tcExpr e@(HsAppType {}) res_ty = tcApp e res_ty tcExpr e@(HsLit x lit) res_ty = do { let lit_ty = hsLitType lit ; tcWrapResult e (HsLit x (convertLit lit)) lit_ty res_ty } -tcExpr (HsPar x expr) res_ty = do { expr' <- tcMonoExprNC expr res_ty +tcExpr (HsPar x expr) res_ty = do { expr' <- tcLExprNC expr res_ty ; return (HsPar x expr') } tcExpr (HsPragE x prag expr) res_ty - = do { expr' <- tcMonoExpr expr res_ty - ; return (HsPragE x (tc_prag prag) expr') } - where - tc_prag :: HsPragE GhcRn -> HsPragE GhcTc - tc_prag (HsPragSCC x1 src ann) = HsPragSCC x1 src ann - tc_prag (HsPragCore x1 src lbl) = HsPragCore x1 src lbl - tc_prag (HsPragTick x1 src info srcInfo) = HsPragTick x1 src info srcInfo - tc_prag (XHsPragE x) = noExtCon x + = do { expr' <- tcLExpr expr res_ty + ; return (HsPragE x (tcExprPrag prag) expr') } tcExpr (HsOverLit x lit) res_ty = do { lit' <- newOverloadedLit lit res_ty @@ -197,7 +197,7 @@ tcExpr (NegApp x expr neg_expr) res_ty = do { (expr', neg_expr') <- tcSyntaxOp NegateOrigin neg_expr [SynAny] res_ty $ \[arg_ty] -> - tcMonoExpr expr (mkCheckExpType arg_ty) + tcLExpr expr (mkCheckExpType arg_ty) ; return (NegApp x expr' neg_expr') } tcExpr e@(HsIPVar _ x) res_ty @@ -332,7 +332,7 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty | (L loc (HsVar _ (L lv op_name))) <- op , op_name `hasKey` dollarIdKey -- Note [Typing rule for ($)] = do { traceTc "Application rule" (ppr op) - ; (arg1', arg1_ty) <- tcInferAppHead arg1 + ; (arg1', arg1_ty) <- tcInferRho arg1 ; let doc = text "The first argument of ($) takes" orig1 = lexprCtOrigin arg1 @@ -373,7 +373,7 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty ; tcWrapResult expr expr' op_res_ty res_ty } - | (L loc (HsRecFld _ (Ambiguous _ lbl))) <- op + | L loc (HsRecFld _ (Ambiguous _ lbl)) <- op , Just sig_ty <- obviousSig (unLoc arg1) -- See Note [Disambiguating record fields] = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty @@ -384,16 +384,24 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty | otherwise = do { traceTc "Non Application rule" (ppr op) - ; (wrap, op', [HsValArg arg1', HsValArg arg2']) - <- tcApp (Just $ mk_op_msg op) - op [HsValArg arg1, HsValArg arg2] res_ty - ; return (mkHsWrap wrap $ OpApp fix arg1' op' arg2') } + ; (op', op_ty) <- tcInferRho op + + ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) + <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty + ; arg1' <- tcArg op arg1 arg1_ty 1 + ; arg2' <- tcArg op arg2 arg2_ty 2 + + ; let expr' = OpApp fix arg1' (mkLHsWrap wrap_fun op') arg2' + ; tcWrapResult expr expr' op_res_ty res_ty } + where + fn_orig = lexprCtOrigin op + -- Right sections, equivalent to \ x -> x `op` expr, or -- \ x -> op x expr tcExpr expr@(SectionR x op arg2) res_ty - = do { (op', op_ty) <- tcInferAppHead op + = do { (op', op_ty) <- tcInferRho op ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty ; wrap_res <- tcSubTypeHR SectionOrigin (Just expr) @@ -408,7 +416,7 @@ tcExpr expr@(SectionR x op arg2) res_ty -- See #13285 tcExpr expr@(SectionL x arg1 op) res_ty - = do { (op', op_ty) <- tcInferAppHead op + = do { (op', op_ty) <- tcInferRho op ; dflags <- getDynFlags -- Note [Left sections] ; let n_reqd_args | xopt LangExt.PostfixOperators dflags = 1 | otherwise = 2 @@ -504,7 +512,7 @@ tcExpr (ExplicitList _ witness exprs) res_ty tcExpr (HsLet x (L l binds) expr) res_ty = do { (binds', expr') <- tcLocalBinds binds $ - tcMonoExpr expr res_ty + tcLExpr expr res_ty ; return (HsLet x (L l binds') expr') } tcExpr (HsCase x scrut matches) res_ty @@ -527,13 +535,13 @@ tcExpr (HsCase x scrut matches) res_ty mc_body = tcBody } tcExpr (HsIf x NoSyntaxExprRn pred b1 b2) res_ty -- Ordinary 'if' - = do { pred' <- tcMonoExpr pred (mkCheckExpType boolTy) + = do { pred' <- tcLExpr pred (mkCheckExpType boolTy) ; res_ty <- tauifyExpType res_ty -- Just like Note [Case branches must never infer a non-tau type] -- in GHC.Tc.Gen.Match (See #10619) - ; b1' <- tcMonoExpr b1 res_ty - ; b2' <- tcMonoExpr b2 res_ty + ; b1' <- tcLExpr b1 res_ty + ; b2' <- tcLExpr b2 res_ty ; return (HsIf x NoSyntaxExprTc pred' b1' b2') } tcExpr (HsIf x fun@(SyntaxExprRn {}) pred b1 b2) res_ty @@ -985,11 +993,24 @@ tcExpr e@(HsRnBracketOut _ brack ps) res_ty ************************************************************************ -} -tcExpr other _ = pprPanic "tcMonoExpr" (ppr other) +tcExpr other _ = pprPanic "tcLExpr" (ppr other) -- Include ArrForm, ArrApp, which shouldn't appear at all -- Also HsTcBracketOut, HsQuasiQuoteE +{- ********************************************************************* +* * + Pragmas on expressions +* * +********************************************************************* -} + +tcExprPrag :: HsPragE GhcRn -> HsPragE GhcTc +tcExprPrag (HsPragSCC x1 src ann) = HsPragSCC x1 src ann +tcExprPrag (HsPragCore x1 src lbl) = HsPragCore x1 src lbl +tcExprPrag (HsPragTick x1 src info srcInfo) = HsPragTick x1 src info srcInfo +tcExprPrag (XHsPragE x) = noExtCon x + + {- ********************************************************************* * * Expression with type signature e::ty @@ -1015,7 +1036,7 @@ tcExprWithSig expr hs_ty -} tcArithSeq :: Maybe (SyntaxExpr GhcRn) -> ArithSeqInfo GhcRn -> ExpRhoType - -> TcM (HsExpr GhcTcId) + -> TcM (HsExpr GhcTc) tcArithSeq witness seq@(From expr) res_ty = do { (wrap, elt_ty, wit') <- arithSeqEltType witness res_ty @@ -1074,111 +1095,118 @@ arithSeqEltType (Just fl) res_ty ************************************************************************ -} --- HsArg is defined in GHC.Hs.Types - -wrapHsArgs :: (NoGhcTc (GhcPass id) ~ GhcRn) - => LHsExpr (GhcPass id) - -> [HsArg (LHsExpr (GhcPass id)) (LHsWcType GhcRn)] - -> LHsExpr (GhcPass id) -wrapHsArgs f [] = f -wrapHsArgs f (HsValArg a : args) = wrapHsArgs (mkHsApp f a) args -wrapHsArgs f (HsTypeArg _ t : args) = wrapHsArgs (mkHsAppType f t) args -wrapHsArgs f (HsArgPar sp : args) = wrapHsArgs (L sp $ HsPar noExtField f) args - -isHsValArg :: HsArg tm ty -> Bool -isHsValArg (HsValArg {}) = True -isHsValArg (HsTypeArg {}) = False -isHsValArg (HsArgPar {}) = False - -isArgPar :: HsArg tm ty -> Bool -isArgPar (HsArgPar {}) = True -isArgPar (HsValArg {}) = False -isArgPar (HsTypeArg {}) = False - -isArgPar_maybe :: HsArg a b -> Maybe (HsArg c d) -isArgPar_maybe (HsArgPar sp) = Just $ HsArgPar sp -isArgPar_maybe _ = Nothing - -type LHsExprArgIn = HsArg (LHsExpr GhcRn) (LHsWcType GhcRn) -type LHsExprArgOut = HsArg (LHsExpr GhcTcId) (LHsWcType GhcRn) - -tcApp1 :: HsExpr GhcRn -- either HsApp or HsAppType - -> ExpRhoType -> TcM (HsExpr GhcTcId) -tcApp1 e res_ty - = do { (wrap, fun, args) <- tcApp Nothing (noLoc e) [] res_ty - ; return (mkHsWrap wrap $ unLoc $ wrapHsArgs fun args) } - -tcApp :: Maybe SDoc -- like "The function `f' is applied to" - -- or leave out to get exactly that message - -> LHsExpr GhcRn -> [LHsExprArgIn] -- Function and args - -> ExpRhoType -> TcM (HsWrapper, LHsExpr GhcTcId, [LHsExprArgOut]) - -- (wrap, fun, args). For an ordinary function application, - -- these should be assembled as (wrap (fun args)). - -- But OpApp is slightly different, so that's why the caller - -- must assemble - -tcApp m_herald (L sp (HsPar _ fun)) args res_ty - = tcApp m_herald fun (HsArgPar sp : args) res_ty - -tcApp m_herald (L _ (HsApp _ fun arg1)) args res_ty - = tcApp m_herald fun (HsValArg arg1 : args) res_ty - -tcApp m_herald (L _ (HsAppType _ fun ty1)) args res_ty - = tcApp m_herald fun (HsTypeArg noSrcSpan ty1 : args) res_ty - -tcApp m_herald fun@(L loc (HsRecFld _ fld_lbl)) args res_ty - | Ambiguous _ lbl <- fld_lbl -- Still ambiguous - , HsValArg (L _ arg) : _ <- filterOut isArgPar args -- A value arg is first - , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates +-- HsExprArg is a specialised verion HsArg is defined in GHC.Hs.Types + +-- The outer location is the location of the application itself +type LHsExprArgIn = HsExprArg 'Renamed +type LHsExprArgOut = HsExprArg 'Typechecked + +-- A GHC specific type, so using TTG only where necessary +data HsExprArg id + = HsExprValArg SrcSpan -- Of the application + (LHsExpr (GhcPass id)) + | HsExprTypeArg SrcSpan -- Of the application + (LHsWcType (NoGhcTc (GhcPass id))) + !(XExprTypeArg id) + | HsExprPar SrcSpan -- Of the (expr) + | HsArgWrap !(XArgWrap id) -- Wrapper, after typechecking + +instance OutputableBndrId id => Outputable (HsExprArg id) where + ppr (HsExprValArg _ tm) = ppr tm + ppr (HsExprTypeArg _ hs_ty _) = char '@' <> ppr hs_ty + ppr (HsExprPar _) = text "HsExprPar" + ppr (HsArgWrap w) = case ghcPass @id of + GhcTc -> text "HsArgWrap" <+> ppr w + _ -> empty + +type family XExprTypeArg id where + XExprTypeArg 'Parsed = NoExtField + XExprTypeArg 'Renamed = NoExtField + XExprTypeArg 'Typechecked = Type + +type family XArgWrap id where + XArgWrap 'Parsed = NoExtField + XArgWrap 'Renamed = NoExtField + XArgWrap 'Typechecked = HsWrapper + +addArgWrap :: HsWrapper -> [LHsExprArgOut] -> [LHsExprArgOut] +addArgWrap wrap args + | isIdHsWrapper wrap = args + | otherwise = HsArgWrap wrap : args + +wrapHsArgs :: LHsExpr GhcTc -> [LHsExprArgOut]-> LHsExpr GhcTc +wrapHsArgs fun args + = go fun args + where + go fun [] = fun + go (L l fun) (HsArgWrap wrap : args) = go (L l $ mkHsWrap wrap fun) args + go fun (HsExprValArg l arg : args) = go (L l $ HsApp noExtField fun arg) args + go fun (HsExprTypeArg l hs_ty ty : args) = go (L l $ HsAppType ty fun hs_ty) args + go fun (HsExprPar l : args) = go (L l $ HsPar noExtField fun) args + +collectHsArgs :: LHsExpr GhcRn -> (LHsExpr GhcRn, [LHsExprArgIn]) +collectHsArgs e = go e [] + where + go (L l (HsPar _ fun)) args = go fun (HsExprPar l : args) + go (L l (HsApp _ fun arg)) args = go fun (HsExprValArg l arg : args) + go (L l (HsAppType _ fun hs_ty)) args = go fun (HsExprTypeArg l hs_ty noExtField : args) + go e args = (e,args) + +isHsValArg :: HsExprArg id -> Bool +isHsValArg (HsExprValArg {}) = True +isHsValArg _ = False + +isArgPar :: HsExprArg id -> Bool +isArgPar (HsExprPar {}) = True +isArgPar _ = False + +tcApp :: HsExpr GhcRn -- either HsApp or HsAppType + -> ExpRhoType -> TcM (HsExpr GhcTc) +tcApp expr res_ty + = do { (fun, args, app_res_ty) <- tcInferApp (noLoc expr) + ; if isTagToEnum fun + then tcTagToEnum expr fun args app_res_ty res_ty + else + do { let expr' = wrapHsArgs fun args + ; addFunResCtxt True (unLoc fun) app_res_ty res_ty $ + tcWrapResult expr (unLoc expr') app_res_ty res_ty } } + +tcInferApp :: LHsExpr GhcRn + -> TcM ( LHsExpr GhcTc -- Function + , [LHsExprArgOut] -- Arguments + , TcSigmaType) -- Inferred type: a sigma-type! +-- Also used by Module.tcRnExpr to implement GHCi :type +tcInferApp expr + | -- Gruesome special case for ambiguous record selectors + L loc (HsRecFld _ fld_lbl) <- fun + , Ambiguous _ lbl <- fld_lbl -- Still ambiguous + , HsExprValArg _ (L _ arg) : _ <- filterOut isArgPar args -- A value arg is first + , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty ; sel_name <- disambiguateSelector lbl sig_tc_ty ; (tc_fun, fun_ty) <- tcInferRecSelId (Unambiguous sel_name lbl) - ; tcFunApp m_herald fun (L loc tc_fun) fun_ty args res_ty } - -tcApp _m_herald (L loc (HsVar _ (L _ fun_id))) args res_ty - -- Special typing rule for tagToEnum# - | fun_id `hasKey` tagToEnumKey - , n_val_args == 1 - = tcTagToEnum loc fun_id args res_ty - where - n_val_args = count isHsValArg args + ; tcInferApp_finish fun (L loc tc_fun) fun_ty args } -tcApp m_herald fun args res_ty + | otherwise = do { (tc_fun, fun_ty) <- tcInferAppHead fun - ; tcFunApp m_herald fun tc_fun fun_ty args res_ty } + ; tcInferApp_finish fun tc_fun fun_ty args } + where + (fun, args) = collectHsArgs expr --------------------- -tcFunApp :: Maybe SDoc -- like "The function `f' is applied to" - -- or leave out to get exactly that message - -> LHsExpr GhcRn -- Renamed function - -> LHsExpr GhcTcId -> TcSigmaType -- Function and its type - -> [LHsExprArgIn] -- Arguments - -> ExpRhoType -- Overall result type - -> TcM (HsWrapper, LHsExpr GhcTcId, [LHsExprArgOut]) - -- (wrapper-for-result, fun, args) - -- For an ordinary function application, - -- these should be assembled as wrap_res[ fun args ] - -- But OpApp is slightly different, so that's why the caller - -- must assemble - --- tcFunApp deals with the general case; --- the special cases are handled by tcApp -tcFunApp m_herald rn_fun tc_fun fun_sigma rn_args res_ty - = do { let orig = lexprCtOrigin rn_fun - - ; traceTc "tcFunApp" (ppr rn_fun <+> dcolon <+> ppr fun_sigma $$ ppr rn_args $$ ppr res_ty) - ; (wrap_fun, tc_args, actual_res_ty) - <- tcArgs rn_fun fun_sigma orig rn_args - (m_herald `orElse` mk_app_msg rn_fun rn_args) - - -- this is just like tcWrapResult, but the types don't line - -- up to call that function - ; wrap_res <- addFunResCtxt True (unLoc rn_fun) actual_res_ty res_ty $ - tcSubTypeDS_NC_O orig GenSigCtxt - (Just $ unLoc $ wrapHsArgs rn_fun rn_args) - actual_res_ty res_ty - - ; return (wrap_res, mkLHsWrap wrap_fun tc_fun, tc_args) } +tcInferApp_finish + :: LHsExpr GhcRn -- Renamed function + -> LHsExpr GhcTc -> TcSigmaType -- Function and its type + -> [LHsExprArgIn] -- Arguments + -> TcM (LHsExpr GhcTc, [LHsExprArgOut], TcSigmaType) + +tcInferApp_finish rn_fun tc_fun fun_sigma rn_args + = do { traceTc "tcInferApp_finish" $ + vcat [ ppr rn_fun <+> dcolon <+> ppr fun_sigma, ppr rn_args ] + + ; (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args + + ; return (tc_fun, tc_args, actual_res_ty) } mk_app_msg :: LHsExpr GhcRn -> [LHsExprArgIn] -> SDoc mk_app_msg fun args = sep [ text "The" <+> text what <+> quotes (ppr expr) @@ -1189,26 +1217,32 @@ mk_app_msg fun args = sep [ text "The" <+> text what <+> quotes (ppr expr) -- Include visible type arguments (but not other arguments) in the herald. -- See Note [Herald for matchExpectedFunTys] in GHC.Tc.Utils.Unify. expr = mkHsAppTypes fun type_app_args - type_app_args = [hs_ty | HsTypeArg _ hs_ty <- args] + type_app_args = [hs_ty | HsExprTypeArg _ hs_ty _ <- args] mk_op_msg :: LHsExpr GhcRn -> SDoc mk_op_msg op = text "The operator" <+> quotes (ppr op) <+> text "takes" ---------------- -tcInferAppHead :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcSigmaType) +tcInferAppHead :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcSigmaType) -- Infer type of the head of an application, -- i.e. the 'f' in (f e1 ... en) -- We get back a SigmaType because we have special cases for -- * A bare identifier (just look it up) -- This case also covers a record selectro HsRecFld -- * An expression with a type signature (e :: ty) +-- +-- Note that [] and (,,) are both HsVar: +-- see Note [Empty lists] and [ExplicitTuple] in GHC.Hs.Expr tcInferAppHead el@(L loc e) = case e of + HsPar _ e -> tcInferAppHead e + HsPragE x prag e -> do { (e',ty) <- tcInferAppHead e + ; return (L loc $ HsPragE x (tcExprPrag prag) e', ty) } HsVar _ (L _ nm) -> add_loc $ tcInferId nm HsRecFld _ f -> add_loc $ tcInferRecSelId f ExprWithTySig _ e hs_ty -> add_loc_ctxt $ tcExprWithSig e hs_ty - _ -> add_loc_ctxt $ tcInferInst (tcExpr e) + _ -> add_loc_ctxt $ tcInfer (tcExpr e) where add_loc_ctxt thing = addErrCtxt (exprCtxt el) $ add_loc thing @@ -1222,35 +1256,42 @@ tcInferAppHead el@(L loc e) -- applications tcArgs :: LHsExpr GhcRn -- ^ The function itself (for err msgs only) -> TcSigmaType -- ^ the (uninstantiated) type of the function - -> CtOrigin -- ^ the origin for the function's type -> [LHsExprArgIn] -- ^ the args - -> SDoc -- ^ the herald for matchActualFunTys - -> TcM (HsWrapper, [LHsExprArgOut], TcSigmaType) + -> TcM ([LHsExprArgOut], TcSigmaType) -- ^ (a wrapper for the function, the tc'd args, result type) -tcArgs fun orig_fun_ty fun_orig orig_args herald - = go [] 1 orig_fun_ty orig_args +tcArgs fun orig_fun_ty orig_args + = go 1 orig_fun_ty orig_args where + fun_orig = lexprCtOrigin fun + herald = mk_app_msg fun orig_args + + -- commented out -- Don't count visible type arguments when determining how many arguments -- an expression is given in an arity mismatch error, since visible type -- arguments reported as a part of the expression herald itself. -- See Note [Herald for matchExpectedFunTys] in GHC.Tc.Utils.Unify. - orig_expr_args_arity = count isHsValArg orig_args + n_val_args = count isHsValArg orig_args fun_is_out_of_scope -- See Note [VTA for out-of-scope functions] = case fun of L _ (HsUnboundVar {}) -> True _ -> False - go _ _ fun_ty [] = return (idHsWrapper, [], fun_ty) + go :: Int -> TcSigmaType -> [LHsExprArgIn] -> TcM ([LHsExprArgOut], TcSigmaType) + go n fun_ty args + = do { traceTc "tcArgs:go {" (ppr n <+> ppr fun_ty $$ ppr args) + ; (args', res_ty) <- go' n fun_ty args + ; traceTc "tcArgs:go }" (ppr res_ty $$ ppr args') + ; return (args', res_ty) } + go' _ fun_ty [] = traceTc "tcArgs:ret" (ppr fun_ty) >> return ([], fun_ty) - go acc_args n fun_ty (HsArgPar sp : args) - = do { (inner_wrap, args', res_ty) <- go acc_args n fun_ty args - ; return (inner_wrap, HsArgPar sp : args', res_ty) - } + go' n fun_ty (HsExprPar sp : args) + = do { (args', res_ty) <- go n fun_ty args + ; return (HsExprPar sp : args', res_ty) } - go acc_args n fun_ty (HsTypeArg l hs_ty_arg : args) + go' n fun_ty (HsExprTypeArg loc hs_ty_arg _ : args) | fun_is_out_of_scope -- See Note [VTA for out-of-scope functions] - = go acc_args (n+1) fun_ty args + = go (n+1) fun_ty args | otherwise = do { (wrap1, upsilon_ty) <- topInstantiateInferred fun_orig fun_ty @@ -1278,30 +1319,22 @@ tcArgs fun orig_fun_ty fun_orig orig_args herald , debugPprType inner_ty , debugPprType insted_ty ]) - ; (inner_wrap, args', res_ty) - <- go acc_args (n+1) insted_ty args - -- inner_wrap :: insted_ty "->" (map typeOf args') -> res_ty - ; let inst_wrap = mkWpTyApps [ty_arg] - ; return ( inner_wrap <.> inst_wrap <.> wrap1 - , HsTypeArg l hs_ty_arg : args' + ; (args', res_ty) <- go (n+1) insted_ty args + ; return ( addArgWrap wrap1 $ HsExprTypeArg loc hs_ty_arg ty_arg : args' , res_ty ) } _ -> ty_app_err upsilon_ty hs_ty_arg } - go acc_args n fun_ty (HsValArg arg : args) + go' n fun_ty (HsExprValArg loc arg : args) = do { (wrap, [arg_ty], res_ty) - <- matchActualFunTysPart herald fun_orig (Just (unLoc fun)) 1 fun_ty - acc_args orig_expr_args_arity - -- wrap :: fun_ty "->" arg_ty -> res_ty + <- matchActualFunTysPart herald fun_orig (Just (unLoc fun)) orig_fun_ty + n_val_args 1 fun_ty ; arg' <- tcArg fun arg arg_ty n - ; (inner_wrap, args', inner_res_ty) - <- go (arg_ty : acc_args) (n+1) res_ty args - -- inner_wrap :: res_ty "->" (map typeOf args') -> inner_res_ty - ; return ( mkWpFun idHsWrapper inner_wrap arg_ty res_ty doc <.> wrap - , HsValArg arg' : args' + ; (args', inner_res_ty) <- go (n+1) res_ty args + ; return ( addArgWrap wrap $ HsExprValArg loc arg' : args' , inner_res_ty ) } - where - doc = text "When checking the" <+> speakNth n <+> - text "argument to" <+> quotes (ppr fun) + + go' n fun_ty (HsArgWrap {} : args) + = do { traceTc "tcArgs:wrap" empty; go n fun_ty args } ty_app_err ty arg = do { (_, ty) <- zonkTidyTcType emptyTidyEnv ty @@ -1393,14 +1426,20 @@ and we had the visible type application ---------------- tcArg :: LHsExpr GhcRn -- The function (for error messages) -> LHsExpr GhcRn -- Actual arguments - -> TcRhoType -- expected arg type + -> TcSigmaType -- expected arg type -> Int -- # of argument - -> TcM (LHsExpr GhcTcId) -- Resulting argument -tcArg fun arg ty arg_no = addErrCtxt (funAppCtxt fun arg arg_no) $ - tcPolyExprNC arg ty + -> TcM (LHsExpr GhcTc) -- Resulting argument +tcArg fun arg ty arg_no + = addErrCtxt (funAppCtxt fun arg arg_no) $ + do { traceTc "tcArg {" $ + vcat [ text "arg #" <> ppr arg_no <+> dcolon <+> ppr ty + , text "arg:" <+> ppr arg ] + ; arg' <- tcPolyExprNC arg ty + ; traceTc "tcArg }" empty + ; return arg' } ---------------- -tcTupArgs :: [LHsTupArg GhcRn] -> [TcSigmaType] -> TcM [LHsTupArg GhcTcId] +tcTupArgs :: [LHsTupArg GhcRn] -> [TcSigmaType] -> TcM [LHsTupArg GhcTc] tcTupArgs args tys = ASSERT( equalLength args tys ) mapM go (args `zip` tys) where @@ -1611,7 +1650,7 @@ in the other order, the extra signature in f2 is reqd. * * ********************************************************************* -} -tcExprSig :: LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTcId, TcType) +tcExprSig :: LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcType) tcExprSig expr (CompleteSig { sig_bndr = poly_id, sig_loc = loc }) = setSrcSpan loc $ -- Sets the location for the implication constraint do { (tv_prs, theta, tau) <- tcInstType tcInstSkolTyVars poly_id @@ -1706,18 +1745,23 @@ CLong, as it should. * * ********************************************************************* -} -tcCheckId :: Name -> ExpRhoType -> TcM (HsExpr GhcTcId) +tcCheckId :: Name -> ExpRhoType -> TcM (HsExpr GhcTc) tcCheckId name res_ty + | name `hasKey` tagToEnumKey + = failWithTc (text "tagToEnum# must appear applied to one argument") + -- tcApp catches the case (tagToEnum# arg) + + | otherwise = do { (expr, actual_res_ty) <- tcInferId name ; traceTc "tcCheckId" (vcat [ppr name, ppr actual_res_ty, ppr res_ty]) - ; addFunResCtxt False (HsVar noExtField (noLoc name)) actual_res_ty res_ty $ + ; addFunResCtxt False expr actual_res_ty res_ty $ tcWrapResultO (OccurrenceOf name) (HsVar noExtField (noLoc name)) expr actual_res_ty res_ty } -tcCheckRecSelId :: HsExpr GhcRn -> AmbiguousFieldOcc GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId) +tcCheckRecSelId :: HsExpr GhcRn -> AmbiguousFieldOcc GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) tcCheckRecSelId rn_expr f@(Unambiguous _ (L _ lbl)) res_ty = do { (expr, actual_res_ty) <- tcInferRecSelId f - ; addFunResCtxt False (HsRecFld noExtField f) actual_res_ty res_ty $ + ; addFunResCtxt False expr actual_res_ty res_ty $ tcWrapResultO (OccurrenceOfRecSel lbl) rn_expr expr actual_res_ty res_ty } tcCheckRecSelId rn_expr (Ambiguous _ lbl) res_ty = case tcSplitFunTy_maybe =<< checkingExpType_maybe res_ty of @@ -1728,7 +1772,7 @@ tcCheckRecSelId rn_expr (Ambiguous _ lbl) res_ty tcCheckRecSelId _ (XAmbiguousFieldOcc nec) _ = noExtCon nec ------------------------ -tcInferRecSelId :: AmbiguousFieldOcc GhcRn -> TcM (HsExpr GhcTcId, TcRhoType) +tcInferRecSelId :: AmbiguousFieldOcc GhcRn -> TcM (HsExpr GhcTc, TcRhoType) tcInferRecSelId (Unambiguous sel (L _ lbl)) = do { (expr', ty) <- tc_infer_id lbl sel ; return (expr', ty) } @@ -1737,14 +1781,10 @@ tcInferRecSelId (Ambiguous _ lbl) tcInferRecSelId (XAmbiguousFieldOcc nec) = noExtCon nec ------------------------ -tcInferId :: Name -> TcM (HsExpr GhcTcId, TcSigmaType) +tcInferId :: Name -> TcM (HsExpr GhcTc, TcSigmaType) -- Look up an occurrence of an Id -- Do not instantiate its type tcInferId id_name - | id_name `hasKey` tagToEnumKey - = failWithTc (text "tagToEnum# must appear applied to one argument") - -- tcApp catches the case (tagToEnum# arg) - | id_name `hasKey` assertIdKey = do { dflags <- getDynFlags ; if gopt Opt_IgnoreAsserts dflags @@ -1756,7 +1796,7 @@ tcInferId id_name ; traceTc "tcInferId" (ppr id_name <+> dcolon <+> ppr ty) ; return (expr, ty) } -tc_infer_assert :: Name -> TcM (HsExpr GhcTcId, TcSigmaType) +tc_infer_assert :: Name -> TcM (HsExpr GhcTc, TcSigmaType) -- Deal with an occurrence of 'assert' -- See Note [Adding the implicit parameter to 'assert'] tc_infer_assert assert_name @@ -1766,7 +1806,7 @@ tc_infer_assert assert_name ; return (mkHsWrap wrap (HsVar noExtField (noLoc assert_error_id)), id_rho) } -tc_infer_id :: RdrName -> Name -> TcM (HsExpr GhcTcId, TcSigmaType) +tc_infer_id :: RdrName -> Name -> TcM (HsExpr GhcTc, TcSigmaType) tc_infer_id lbl id_name = do { thing <- tcLookup id_name ; case thing of @@ -1817,7 +1857,7 @@ tc_infer_id lbl id_name | otherwise = return () -tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTcId) +tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Typecheck an occurrence of an unbound Id -- -- Some of these started life as a true expression hole "_". @@ -1886,60 +1926,50 @@ the users that complain. -} -tcTagToEnum :: SrcSpan -> Name -> [LHsExprArgIn] -> ExpRhoType - -> TcM (HsWrapper, LHsExpr GhcTcId, [LHsExprArgOut]) +isTagToEnum :: LHsExpr GhcTc -> Bool +isTagToEnum (L _ (HsVar _ (L _ fun_id))) = fun_id `hasKey` tagToEnumKey +isTagToEnum _ = False + +tcTagToEnum :: HsExpr GhcRn -> LHsExpr GhcTc -> [LHsExprArgOut] + -> TcSigmaType -> ExpRhoType + -> TcM (HsExpr GhcTc) -- tagToEnum# :: forall a. Int# -> a -- See Note [tagToEnum#] Urgh! -tcTagToEnum loc fun_name args res_ty - = do { fun <- tcLookupId fun_name - - ; let pars1 = mapMaybe isArgPar_maybe before - pars2 = mapMaybe isArgPar_maybe after - -- args contains exactly one HsValArg - (before, _:after) = break isHsValArg args - - ; arg <- case filterOut isArgPar args of - [HsTypeArg _ hs_ty_arg, HsValArg term_arg] - -> do { ty_arg <- tcHsTypeApp hs_ty_arg liftedTypeKind - ; _ <- tcSubTypeDS (OccurrenceOf fun_name) GenSigCtxt ty_arg res_ty - -- other than influencing res_ty, we just - -- don't care about a type arg passed in. - -- So drop the evidence. - ; return term_arg } - [HsValArg term_arg] -> do { _ <- expTypeToType res_ty - ; return term_arg } - _ -> too_many_args "tagToEnum#" args - - ; res_ty <- readExpType res_ty +tcTagToEnum expr fun args app_res_ty res_ty + = do { res_ty <- readExpType res_ty ; ty' <- zonkTcType res_ty -- Check that the type is algebraic - ; let mb_tc_app = tcSplitTyConApp_maybe ty' - Just (tc, tc_args) = mb_tc_app - ; checkTc (isJust mb_tc_app) - (mk_error ty' doc1) + ; case tcSplitTyConApp_maybe ty' of { + Nothing -> do { addErrTc (mk_error ty' doc1) + ; vanilla_result } ; + Just (tc, tc_args) -> - -- Look through any type family + do { -- Look through any type family ; fam_envs <- tcGetFamInstEnvs - ; let (rep_tc, rep_args, coi) - = tcLookupDataFamInst fam_envs tc tc_args - -- coi :: tc tc_args ~R rep_tc rep_args - - ; checkTc (isEnumerationTyCon rep_tc) - (mk_error ty' doc2) - - ; arg' <- tcMonoExpr arg (mkCheckExpType intPrimTy) - ; let fun' = L loc (mkHsWrap (WpTyApp rep_ty) (HsVar noExtField (L loc fun))) - rep_ty = mkTyConApp rep_tc rep_args - out_args = concat - [ pars1 - , [HsValArg arg'] - , pars2 - ] - - ; return (mkWpCastR (mkTcSymCo coi), fun', out_args) } - -- coi is a Representational coercion + ; case tcLookupDataFamInst_maybe fam_envs tc tc_args of { + Nothing -> do { check_enumeration ty' tc + ; vanilla_result } ; + Just (rep_tc, rep_args, coi) -> + + do { -- coi :: tc tc_args ~R rep_tc rep_args + check_enumeration ty' rep_tc + ; let val_arg = dropWhile (not . isHsValArg) args + rep_ty = mkTyConApp rep_tc rep_args + fun' = mkLHsWrap (WpTyApp rep_ty) fun + expr' = wrapHsArgs fun' val_arg + df_wrap = mkWpCastR (mkTcSymCo coi) + ; return (mkHsWrap df_wrap (unLoc expr')) }}}}} + where + vanilla_result + = do { let expr' = wrapHsArgs fun args + ; tcWrapResult expr (unLoc expr') app_res_ty res_ty } + + check_enumeration ty' tc + | isEnumerationTyCon tc = return () + | otherwise = addErrTc (mk_error ty' doc2) + doc1 = vcat [ text "Specify the type by giving a type signature" , text "e.g. (tagToEnum# x) :: Bool" ] doc2 = text "Result type must be an enumeration type" @@ -1950,18 +1980,6 @@ tcTagToEnum loc fun_name args res_ty <+> text "at type" <+> ppr ty) 2 what -too_many_args :: String -> [LHsExprArgIn] -> TcM a -too_many_args fun args - = failWith $ - hang (text "Too many type arguments to" <+> text fun <> colon) - 2 (sep (map pp args)) - where - pp (HsValArg e) = ppr e - pp (HsTypeArg _ (HsWC { hswc_body = L _ t })) = pprHsType t - pp (HsTypeArg _ (XHsWildCardBndrs nec)) = noExtCon nec - pp (HsArgPar _) = empty - - {- ************************************************************************ * * @@ -2374,7 +2392,7 @@ tcRecordBinds :: ConLike -> [TcType] -- Expected type for each field -> HsRecordBinds GhcRn - -> TcM (HsRecordBinds GhcTcId) + -> TcM (HsRecordBinds GhcTc) tcRecordBinds con_like arg_tys (HsRecFields rbinds dd) = do { mb_binds <- mapM do_bind rbinds @@ -2384,7 +2402,7 @@ tcRecordBinds con_like arg_tys (HsRecFields rbinds dd) flds_w_tys = zipEqual "tcRecordBinds" fields arg_tys do_bind :: LHsRecField GhcRn (LHsExpr GhcRn) - -> TcM (Maybe (LHsRecField GhcTcId (LHsExpr GhcTcId))) + -> TcM (Maybe (LHsRecField GhcTc (LHsExpr GhcTc))) do_bind (L l fld@(HsRecField { hsRecFieldLbl = f , hsRecFieldArg = rhs })) @@ -2398,7 +2416,7 @@ tcRecordUpd :: ConLike -> [TcType] -- Expected type for each field -> [LHsRecField' (AmbiguousFieldOcc GhcTc) (LHsExpr GhcRn)] - -> TcM [LHsRecUpdField GhcTcId] + -> TcM [LHsRecUpdField GhcTc] tcRecordUpd con_like arg_tys rbinds = fmap catMaybes $ mapM do_bind rbinds where @@ -2406,7 +2424,7 @@ tcRecordUpd con_like arg_tys rbinds = fmap catMaybes $ mapM do_bind rbinds flds_w_tys = zipEqual "tcRecordUpd" fields arg_tys do_bind :: LHsRecField' (AmbiguousFieldOcc GhcTc) (LHsExpr GhcRn) - -> TcM (Maybe (LHsRecUpdField GhcTcId)) + -> TcM (Maybe (LHsRecUpdField GhcTc)) do_bind (L l fld@(HsRecField { hsRecFieldLbl = L loc af , hsRecFieldArg = rhs })) = do { let lbl = rdrNameAmbiguousFieldOcc af @@ -2501,19 +2519,12 @@ checkMissingFields con_like rbinds Boring and alphabetical: -} -addExprErrCtxt :: LHsExpr GhcRn -> TcM a -> TcM a -addExprErrCtxt expr = addErrCtxt (exprCtxt expr) - -exprCtxt :: LHsExpr GhcRn -> SDoc -exprCtxt expr - = hang (text "In the expression:") 2 (ppr (stripParensHsExpr expr)) - fieldCtxt :: FieldLabelString -> SDoc fieldCtxt field_name = text "In the" <+> quotes (ppr field_name) <+> ptext (sLit "field of a record") addFunResCtxt :: Bool -- There is at least one argument - -> HsExpr GhcRn -> TcType -> ExpRhoType + -> HsExpr GhcTc -> TcType -> ExpRhoType -> TcM a -> TcM a -- When we have a mis-match in the return type of a function -- try to give a helpful message about too many/few arguments ===================================== compiler/GHC/Tc/Gen/Expr.hs-boot ===================================== @@ -8,14 +8,13 @@ import GHC.Hs.Extension ( GhcRn, GhcTcId ) tcPolyExpr :: LHsExpr GhcRn -> TcSigmaType -> TcM (LHsExpr GhcTcId) -tcMonoExpr, tcMonoExprNC - :: LHsExpr GhcRn -> ExpRhoType -> TcM (LHsExpr GhcTcId) +tcLExpr, tcLExprNC + :: LHsExpr GhcRn -> ExpRhoType -> TcM (LHsExpr GhcTcId) +tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId) tcInferRho, tcInferRhoNC :: LHsExpr GhcRn-> TcM (LHsExpr GhcTcId, TcRhoType) -tcInferAppHead :: LHsExpr GhcRn -> TcM (LHsExpr GhcTcId, TcSigmaType) - tcSyntaxOp :: CtOrigin -> SyntaxExprRn -> [SyntaxOpType] -- ^ shape of syntax operator arguments ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -37,7 +37,8 @@ where import GhcPrelude import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcInferRhoNC, tcInferRho - , tcCheckId, tcMonoExpr, tcMonoExprNC, tcPolyExpr ) + , tcCheckId, tcLExpr, tcLExprNC, tcExpr + , tcPolyExpr ) import GHC.Types.Basic (LexicalFixity(..)) import GHC.Hs @@ -335,7 +336,7 @@ tcDoStmts ctxt _ _ = pprPanic "tcDoStmts" (pprStmtContext ctxt) tcBody :: LHsExpr GhcRn -> ExpRhoType -> TcM (LHsExpr GhcTcId) tcBody body res_ty = do { traceTc "tcBody" (ppr res_ty) - ; tcMonoExpr body res_ty + ; tcLExpr body res_ty } {- @@ -415,7 +416,7 @@ tcStmtsAndThen ctxt stmt_chk (L loc stmt : stmts) res_ty thing_inside tcGuardStmt :: TcExprStmtChecker tcGuardStmt _ (BodyStmt _ guard _ _) res_ty thing_inside - = do { guard' <- tcMonoExpr guard (mkCheckExpType boolTy) + = do { guard' <- tcLExpr guard (mkCheckExpType boolTy) ; thing <- thing_inside res_ty ; return (BodyStmt boolTy guard' noSyntaxExpr noSyntaxExpr, thing) } @@ -448,21 +449,21 @@ tcLcStmt :: TyCon -- The list type constructor ([]) -> TcExprStmtChecker tcLcStmt _ _ (LastStmt x body noret _) elt_ty thing_inside - = do { body' <- tcMonoExprNC body elt_ty + = do { body' <- tcLExprNC body elt_ty ; thing <- thing_inside (panic "tcLcStmt: thing_inside") ; return (LastStmt x body' noret noSyntaxExpr, thing) } -- A generator, pat <- rhs tcLcStmt m_tc ctxt (BindStmt _ pat rhs _ _) elt_ty thing_inside = do { pat_ty <- newFlexiTyVarTy liftedTypeKind - ; rhs' <- tcMonoExpr rhs (mkCheckExpType $ mkTyConApp m_tc [pat_ty]) + ; rhs' <- tcLExpr rhs (mkCheckExpType $ mkTyConApp m_tc [pat_ty]) ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside elt_ty ; return (mkTcBindStmt pat' rhs', thing) } -- A boolean guard tcLcStmt _ _ (BodyStmt _ rhs _ _) elt_ty thing_inside - = do { rhs' <- tcMonoExpr rhs (mkCheckExpType boolTy) + = do { rhs' <- tcLExpr rhs (mkCheckExpType boolTy) ; thing <- thing_inside elt_ty ; return (BodyStmt boolTy rhs' noSyntaxExpr noSyntaxExpr, thing) } @@ -563,7 +564,7 @@ tcMcStmt _ (LastStmt x body noret return_op) res_ty thing_inside = do { (body', return_op') <- tcSyntaxOp MCompOrigin return_op [SynRho] res_ty $ \ [a_ty] -> - tcMonoExprNC body (mkCheckExpType a_ty) + tcLExprNC body (mkCheckExpType a_ty) ; thing <- thing_inside (panic "tcMcStmt: thing_inside") ; return (LastStmt x body' noret return_op', thing) } @@ -579,7 +580,7 @@ tcMcStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside <- tcSyntaxOp MCompOrigin bind_op [SynRho, SynFun SynAny SynRho] res_ty $ \ [rhs_ty, pat_ty, new_res_ty] -> - do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) + do { rhs' <- tcLExprNC rhs (mkCheckExpType rhs_ty) ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside (mkCheckExpType new_res_ty) ; return (rhs', pat', thing, new_res_ty) } @@ -605,7 +606,7 @@ tcMcStmt _ (BodyStmt _ rhs then_op guard_op) res_ty thing_inside <- tcSyntaxOp MCompOrigin guard_op [SynAny] (mkCheckExpType rhs_ty) $ \ [test_ty] -> - tcMonoExpr rhs (mkCheckExpType test_ty) + tcLExpr rhs (mkCheckExpType test_ty) ; thing <- thing_inside (mkCheckExpType new_res_ty) ; return (thing, rhs', rhs_ty, guard_op') } ; return (BodyStmt rhs_ty rhs' then_op' guard_op', thing) } @@ -665,7 +666,7 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap (mkCheckExpType using_arg_ty) $ \res_ty' -> do { by' <- case by of Nothing -> return Nothing - Just e -> do { e' <- tcMonoExpr e + Just e -> do { e' <- tcLExpr e (mkCheckExpType by_e_ty) ; return (Just e') } @@ -825,7 +826,7 @@ tcMcStmt _ stmt _ _ tcDoStmt :: TcExprStmtChecker tcDoStmt _ (LastStmt x body noret _) res_ty thing_inside - = do { body' <- tcMonoExprNC body res_ty + = do { body' <- tcLExprNC body res_ty ; thing <- thing_inside (panic "tcDoStmt: thing_inside") ; return (LastStmt x body' noret noSyntaxExpr, thing) } @@ -838,7 +839,7 @@ tcDoStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside ((rhs', pat', new_res_ty, thing), bind_op') <- tcSyntaxOp DoOrigin bind_op [SynRho, SynFun SynAny SynRho] res_ty $ \ [rhs_ty, pat_ty, new_res_ty] -> - do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) + do { rhs' <- tcLExprNC rhs (mkCheckExpType rhs_ty) ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ thing_inside (mkCheckExpType new_res_ty) ; return (rhs', pat', new_res_ty, thing) } @@ -866,7 +867,7 @@ tcDoStmt _ (BodyStmt _ rhs then_op _) res_ty thing_inside ; ((rhs', rhs_ty, thing), then_op') <- tcSyntaxOp DoOrigin then_op [SynRho, SynRho] res_ty $ \ [rhs_ty, new_res_ty] -> - do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) + do { rhs' <- tcLExprNC rhs (mkCheckExpType rhs_ty) ; thing <- thing_inside (mkCheckExpType new_res_ty) ; return (rhs', rhs_ty, thing) } ; return (BodyStmt rhs_ty rhs' then_op' noSyntaxExpr, thing) } @@ -882,7 +883,7 @@ tcDoStmt ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names ; tcExtendIdEnv tup_ids $ do { ((stmts', (ret_op', tup_rets)), stmts_ty) - <- tcInferInst $ \ exp_ty -> + <- tcInfer $ \ exp_ty -> tcStmtsAndThen ctxt tcDoStmt stmts exp_ty $ \ inner_res_ty -> do { tup_rets <- zipWithM tcCheckId tup_names (map mkCheckExpType tup_elt_tys) @@ -894,7 +895,7 @@ tcDoStmt ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names ; return (ret_op', tup_rets) } ; ((_, mfix_op'), mfix_res_ty) - <- tcInferInst $ \ exp_ty -> + <- tcInfer $ \ exp_ty -> tcSyntaxOp DoOrigin mfix_op [synKnownType (mkVisFunTy tup_ty stmts_ty)] exp_ty $ \ _ -> return () @@ -959,7 +960,7 @@ When typechecking do { bar; ... } :: IO () we want to typecheck 'bar' in the knowledge that it should be an IO thing, pushing info from the context into the RHS. To do this, we check the -rebindable syntax first, and push that information into (tcMonoExprNC rhs). +rebindable syntax first, and push that information into (tcLExprNC rhs). Otherwise the error shows up when checking the rebindable syntax, and the expected/inferred stuff is back to front (see #3613). @@ -991,7 +992,7 @@ tcApplicativeStmts tcApplicativeStmts ctxt pairs rhs_ty thing_inside = do { body_ty <- newFlexiTyVarTy liftedTypeKind ; let arity = length pairs - ; ts <- replicateM (arity-1) $ newInferExpTypeInst + ; ts <- replicateM (arity-1) $ newInferExpType ; exp_tys <- replicateM arity $ newFlexiTyVarTy liftedTypeKind ; pat_tys <- replicateM arity $ newFlexiTyVarTy liftedTypeKind ; let fun_ty = mkVisFunTys pat_tys body_ty @@ -1035,7 +1036,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside }, pat_ty, exp_ty) = setSrcSpan (combineSrcSpans (getLoc pat) (getLoc rhs)) $ addErrCtxt (pprStmtInCtxt ctxt (mkBindStmt pat rhs)) $ - do { rhs' <- tcMonoExprNC rhs (mkCheckExpType exp_ty) + do { rhs' <- tcLExprNC rhs (mkCheckExpType exp_ty) ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ return () ; fail_op' <- tcMonadFailOp (DoPatOrigin pat) pat' fail_op body_ty @@ -1051,7 +1052,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside = do { (stmts', (ret',pat')) <- tcStmtsAndThen ctxt tcDoStmt stmts (mkCheckExpType exp_ty) $ \res_ty -> do - { L _ ret' <- tcMonoExprNC (noLoc ret) res_ty + { ret' <- tcExpr ret res_ty ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $ return () ; return (ret', pat') ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -28,7 +28,7 @@ where import GhcPrelude -import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferAppHead ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferRho ) import GHC.Hs import GHC.Tc.Utils.Zonk @@ -116,7 +116,7 @@ tcInferPat :: HsMatchContext GhcRn -> LPat GhcRn -> TcM a -> TcM ((LPat GhcTcId, a), TcSigmaType) tcInferPat ctxt pat thing_inside - = tcInferInst $ \ exp_ty -> -- The ir_inst flag is irrelevant in tcPat + = tcInfer $ \ exp_ty -> tc_lpat pat exp_ty penv thing_inside where penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = PatOrigin } @@ -399,12 +399,17 @@ tc_pat penv (AsPat x (L nm_loc name) pat) pat_ty thing_inside tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside = do { - -- Using tcInferAppHead here, rather than tcMonoExpr, lets us - -- have view functions with types like: - -- (forall a. blah) -> forall b. burble - -- So the overall_pat_ty is (forall a. blah), while the - -- inner pattern is checked with (forall b. burble) - ; (expr',expr_ty) <- tcInferAppHead expr + -- We use tcInferRho here. + -- If we have a view function with types like: + -- blah -> forall b. burble + -- then simple-subsumption means that 'forall b' won't be instantiated + -- so we can typecheck the inner pattern with that type + -- Until simple subsumption, it'll be deeply instantiated, but + -- probably no one will notice. + -- An exotic example: + -- pair :: forall a. a -> forall b. b -> (a,b) + -- f (pair True -> x) = ...here (x :: forall b. b -> (Bool,b)) + ; (expr',expr_ty) <- tcInferRho expr -- Expression must be a function ; let expr_orig = lexprCtOrigin expr ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -201,7 +201,7 @@ generateRuleConstraints ty_bndrs tm_bndrs lhs rhs do { -- See Note [Solve order for RULES] ((lhs', rule_ty), lhs_wanted) <- captureConstraints (tcInferRho lhs) ; (rhs', rhs_wanted) <- captureConstraints $ - tcMonoExpr rhs (mkCheckExpType rule_ty) + tcLExpr rhs (mkCheckExpType rule_ty) ; let all_lhs_wanted = bndr_wanted `andWC` lhs_wanted ; return (id_bndrs, lhs', all_lhs_wanted, rhs', rhs_wanted, rule_ty) } } ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -617,7 +617,7 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; meta_exp_ty <- tcTExpTy m_var res_ty ; expr' <- setStage pop_stage $ setConstraintVar lie_var $ - tcMonoExpr expr (mkCheckExpType meta_exp_ty) + tcLExpr expr (mkCheckExpType meta_exp_ty) ; untypeq <- tcLookupId unTypeQName ; let expr'' = mkHsApp (mkLHsWrap (applyQuoteWrapper q) @@ -640,7 +640,7 @@ tcTopSplice expr res_ty -- Top level splices must still be of type Q (TExp a) ; meta_exp_ty <- tcTExpTy q_type res_ty ; q_expr <- tcTopSpliceExpr Typed $ - tcMonoExpr expr (mkCheckExpType meta_exp_ty) + tcLExpr expr (mkCheckExpType meta_exp_ty) ; lcl_env <- getLclEnv ; let delayed_splice = DelayedSplice lcl_env expr res_ty q_expr @@ -677,7 +677,7 @@ runTopSplice (DelayedSplice lcl_env orig_expr res_ty q_expr) captureConstraints $ addErrCtxt (spliceResultDoc zonked_q_expr) $ do { (exp3, _fvs) <- rnLExpr expr2 - ; tcMonoExpr exp3 (mkCheckExpType zonked_ty)} + ; tcLExpr exp3 (mkCheckExpType zonked_ty)} ; ev <- simplifyTop wcs ; return $ unLoc (mkHsDictLet (EvBinds ev) res) } ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -1787,8 +1787,8 @@ check_main dflags tcg_env explicit_mod_hdr export_ies ; (ev_binds, main_expr) <- checkConstraints skol_info [] [] $ addErrCtxt mainCtxt $ - tcMonoExpr (L loc (HsVar noExtField (L loc main_name))) - (mkCheckExpType io_ty) + tcLExpr (L loc (HsVar noExtField (L loc main_name))) + (mkCheckExpType io_ty) -- See Note [Root-main Id] -- Construct the binding @@ -2495,8 +2495,7 @@ tcRnExpr hsc_env mode rdr_expr ((tclvl, res_ty), lie) <- captureTopConstraints $ pushTcLevelM $ - do { (_tc_expr, expr_ty) <- tc_infer rn_expr - ; return expr_ty } ; + tc_infer rn_expr ; -- Generalise (qtvs, dicts, _, residual, _) @@ -2522,8 +2521,10 @@ tcRnExpr hsc_env mode rdr_expr return (snd (normaliseType fam_envs Nominal ty)) } where - tc_infer | inst = tcInferRhoNC - | otherwise = tcInferAppHead + tc_infer expr | inst = do { (_, ty) <- tcInferRhoNC expr + ; return ty } + | otherwise = do { (_, _, ty) <- tcInferApp expr + ; return ty } -- See Note [TcRnExprMode] (inst, infer_mode, perhaps_disable_default_warnings) = case mode of TM_Inst -> (True, NoRestrictions, id) ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -1063,7 +1063,7 @@ tcTryM :: TcRn r -> TcRn (Maybe r) tcTryM thing_inside = do { either_res <- tryM thing_inside ; return (case either_res of - Left _ -> Nothing + Left exn -> pprTrace "tcTryM" (text (show exn)) Nothing Right r -> Just r) } -- In the Left case the exception is always the IOEnv -- built-in in exception; see IOEnv.failM ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Tc.Utils.TcMType ( -- Expected types ExpType(..), ExpSigmaType, ExpRhoType, mkCheckExpType, - newInferExpType, newInferExpTypeInst, newInferExpTypeNoInst, + newInferExpType, readExpType, readExpType_maybe, expTypeToType, checkingExpType_maybe, checkingExpType, tauifyExpType, inferResultToType, @@ -440,21 +440,14 @@ test gadt/gadt-escape1. -- actual data definition is in GHC.Tc.Utils.TcType --- | Make an 'ExpType' suitable for inferring a type of kind * or #. -newInferExpTypeNoInst :: TcM ExpSigmaType -newInferExpTypeNoInst = newInferExpType False - -newInferExpTypeInst :: TcM ExpRhoType -newInferExpTypeInst = newInferExpType True - -newInferExpType :: Bool -> TcM ExpType -newInferExpType inst +newInferExpType :: TcM ExpType +newInferExpType = do { u <- newUnique ; tclvl <- getTcLevel - ; traceTc "newOpenInferExpType" (ppr u <+> ppr inst <+> ppr tclvl) + ; traceTc "newInferExpType" (ppr u <+> ppr tclvl) ; ref <- newMutVar Nothing ; return (Infer (IR { ir_uniq = u, ir_lvl = tclvl - , ir_ref = ref, ir_inst = inst })) } + , ir_ref = ref })) } -- | Extract a type out of an ExpType, if one exists. But one should always -- exist. Unless you're quite sure you know what you're doing. ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -368,13 +368,6 @@ data InferResult , ir_lvl :: TcLevel -- See Note [TcLevel of ExpType] in GHC.Tc.Utils.TcMType - , ir_inst :: Bool - -- True <=> deeply instantiate before returning - -- i.e. return a RhoType - -- False <=> do not instantiate before returning - -- i.e. return a SigmaType - -- See Note [Deep instantiation of InferResult] in GHC.Tc.Utils.Unify - , ir_ref :: IORef (Maybe TcType) } -- The type that fills in this hole should be a Type, -- that is, its kind should be (TYPE rr) for some rr @@ -387,9 +380,8 @@ instance Outputable ExpType where ppr (Infer ir) = ppr ir instance Outputable InferResult where - ppr (IR { ir_uniq = u, ir_lvl = lvl - , ir_inst = inst }) - = text "Infer" <> braces (ppr u <> comma <> ppr lvl <+> ppr inst) + ppr (IR { ir_uniq = u, ir_lvl = lvl }) + = text "Infer" <> braces (ppr u <> comma <> ppr lvl) -- | Make an 'ExpType' suitable for checking. mkCheckExpType :: TcType -> ExpType ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Tc.Utils.Unify ( -------------------------------- -- Holes - tcInferInst, tcInferNoInst, + tcInfer, matchExpectedListTy, matchExpectedTyConApp, matchExpectedAppTy, @@ -199,8 +199,8 @@ matchExpectedFunTys herald arity orig_ty thing_inside ------------ defer :: [ExpSigmaType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper) defer acc_arg_tys n fun_ty - = do { more_arg_tys <- replicateM n newInferExpTypeNoInst - ; res_ty <- newInferExpTypeInst + = do { more_arg_tys <- replicateM n newInferExpType + ; res_ty <- newInferExpType ; result <- thing_inside (reverse acc_arg_tys ++ more_arg_tys) res_ty ; more_arg_tys <- mapM readExpType more_arg_tys ; res_ty <- readExpType res_ty @@ -231,22 +231,24 @@ matchActualFunTys :: SDoc -- See Note [Herald for matchExpectedFunTys] -> TcM (HsWrapper, [TcSigmaType], TcSigmaType) -- If matchActualFunTys n ty = (wrap, [t1,..,tn], ty_r) -- then wrap : ty ~> (t1 -> ... -> tn -> ty_r) -matchActualFunTys herald ct_orig mb_thing arity ty - = matchActualFunTysPart herald ct_orig mb_thing arity ty [] arity +matchActualFunTys herald ct_orig mb_thing n_val_args_wanted fun_ty + = matchActualFunTysPart herald ct_orig mb_thing fun_ty n_val_args_wanted + n_val_args_wanted fun_ty -- | Variant of 'matchActualFunTys' that works when supplied only part -- (that is, to the right of some arrows) of the full function type matchActualFunTysPart :: SDoc -- See Note [Herald for matchExpectedFunTys] -> CtOrigin -> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType - -> Arity - -> TcSigmaType - -> [TcSigmaType] -- reversed args. See (*) below. - -> Arity -- overall arity of the function, for errs + -> TcSigmaType -- Original function type + -> Arity -- And number of args to which it is applied + -> Arity -- Number of new value args wanted + -> TcSigmaType -- Type to analyse -> TcM (HsWrapper, [TcSigmaType], TcSigmaType) -matchActualFunTysPart herald ct_orig mb_thing arity orig_ty - orig_old_args full_arity - = go arity orig_old_args orig_ty +matchActualFunTysPart herald ct_orig mb_thing + orig_fun_ty n_val_args_in_call + n_val_args_wanted fun_ty + = go n_val_args_wanted fun_ty -- Does not allocate unnecessary meta variables: if the input already is -- a function, we just take it apart. Not only is this efficient, -- it's important for higher rank: the argument might be of form @@ -274,36 +276,35 @@ matchActualFunTysPart herald ct_orig mb_thing arity orig_ty -- -- Refactoring is welcome. go :: Arity - -> [TcSigmaType] -- accumulator of arguments (reversed) -> TcSigmaType -- the remainder of the type as we're processing -> TcM (HsWrapper, [TcSigmaType], TcSigmaType) - go 0 _ ty = return (idHsWrapper, [], ty) + go 0 ty = return (idHsWrapper, [], ty) - go n acc_args ty + go n ty | not (null tvs && null theta) = do { (wrap1, rho) <- topInstantiate ct_orig ty - ; (wrap2, arg_tys, res_ty) <- go n acc_args rho + ; (wrap2, arg_tys, res_ty) <- go n rho ; return (wrap2 <.> wrap1, arg_tys, res_ty) } where (tvs, theta, _) = tcSplitSigmaTy ty - go n acc_args ty - | Just ty' <- tcView ty = go n acc_args ty' + go n ty + | Just ty' <- tcView ty = go n ty' - go n acc_args (FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty }) + go n (FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty }) = ASSERT( af == VisArg ) - do { (wrap_res, tys, ty_r) <- go (n-1) (arg_ty : acc_args) res_ty + do { (wrap_res, tys, ty_r) <- go (n-1) res_ty ; return ( mkWpFun idHsWrapper wrap_res arg_ty ty_r doc , arg_ty : tys, ty_r ) } where doc = text "When inferring the argument type of a function with type" <+> - quotes (ppr orig_ty) + quotes (ppr orig_fun_ty) - go n acc_args ty@(TyVarTy tv) + go n ty@(TyVarTy tv) | isMetaTyVar tv = do { cts <- readMetaTyVar tv ; case cts of - Indirect ty' -> go n acc_args ty' + Indirect ty' -> go n ty' Flexi -> defer n ty } -- In all other cases we bale out into ordinary unification @@ -321,8 +322,7 @@ matchActualFunTysPart herald ct_orig mb_thing arity orig_ty -- -- But in that case we add specialized type into error context -- anyway, because it may be useful. See also #9605. - go n acc_args ty = addErrCtxtM (mk_ctxt (reverse acc_args) ty) $ - defer n ty + go n ty = addErrCtxtM mk_ctxt (defer n ty) ------------ defer n fun_ty @@ -333,16 +333,16 @@ matchActualFunTysPart herald ct_orig mb_thing arity orig_ty ; return (mkWpCastN co, arg_tys, res_ty) } ------------ - mk_ctxt :: [TcSigmaType] -> TcSigmaType -> TidyEnv -> TcM (TidyEnv, MsgDoc) - mk_ctxt arg_tys res_ty env - = do { let ty = mkVisFunTys arg_tys res_ty - ; (env1, zonked) <- zonkTidyTcType env ty - -- zonking might change # of args - ; let (zonked_args, _) = tcSplitFunTys zonked - n_actual = length zonked_args - (env2, unzonked) = tidyOpenType env1 ty + mk_ctxt :: TidyEnv -> TcM (TidyEnv, MsgDoc) + mk_ctxt env + = do { (env1, zonked) <- zonkTidyTcType env orig_fun_ty + -- Zonking might change # of args + ; let (zonked_args, _) = tcSplitPiTys zonked + n_val_args_in_type = count isVisibleBinder zonked_args + (env2, unzonked) = tidyOpenType env1 orig_fun_ty ; return ( env2 - , mk_fun_tys_msg unzonked zonked n_actual full_arity herald) } + , mk_fun_tys_msg unzonked zonked n_val_args_in_type + n_val_args_in_call herald) } mk_fun_tys_msg :: TcType -- the full type passed in (unzonked) -> TcType -- the full type passed in (zonked) @@ -350,15 +350,15 @@ mk_fun_tys_msg :: TcType -- the full type passed in (unzonked) -> Arity -- the # of args wanted -> SDoc -- overall herald -> SDoc -mk_fun_tys_msg full_ty ty n_args full_arity herald - = herald <+> speakNOf full_arity (text "argument") <> comma $$ - if n_args == full_arity +mk_fun_tys_msg full_ty ty n_args_in_type n_args_in_call herald + = herald <+> speakNOf n_args_in_call (text "argument") <> comma $$ + if n_args_in_type == n_args_in_call then text "its type is" <+> quotes (pprType full_ty) <> comma $$ text "it is specialized to" <+> quotes (pprType ty) else sep [text "but its type" <+> quotes (pprType ty), - if n_args == 0 then text "has none" - else text "has only" <+> speakN n_args] + if n_args_in_type == 0 then text "has none" + else text "has only" <+> speakN n_args_in_type] ---------------------- matchExpectedListTy :: TcRhoType -> TcM (TcCoercionN, TcRhoType) @@ -564,8 +564,7 @@ tcSubTypeET orig ctxt (Check ty_actual) ty_expected tcSubTypeET _ _ (Infer inf_res) ty_expected = do { co <- fillInferResult ty_expected inf_res - -- In patterns we ignore the ir_inst field - -- and never instantatiate + -- In patterns we do not instantatiate ; return (mkWpCastN (mkTcSymCo co)) } @@ -866,16 +865,9 @@ tcWrapResultO orig rn_expr expr actual_ty res_ty -- | Infer a type using a fresh ExpType -- See also Note [ExpType] in GHC.Tc.Utils.TcMType --- Does not attempt to instantiate the inferred type -tcInferNoInst :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType) -tcInferNoInst = tcInfer False - -tcInferInst :: (ExpRhoType -> TcM a) -> TcM (a, TcRhoType) -tcInferInst = tcInfer True - -tcInfer :: Bool -> (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType) -tcInfer instantiate tc_check - = do { res_ty <- newInferExpType instantiate +tcInfer :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType) +tcInfer tc_check + = do { res_ty <- newInferExpType ; result <- tc_check res_ty ; res_ty <- readExpType res_ty ; return (result, res_ty) } @@ -884,16 +876,11 @@ instantiateAndFillInferResult :: CtOrigin -> TcType -> InferResult -> TcM HsWrap -- If wrap = instantiateAndFillInferResult t1 t2 -- => wrap :: t1 ~> t2 -- See Note [Deep instantiation of InferResult] -instantiateAndFillInferResult orig ty inf_res@(IR { ir_inst = instantiate_me }) - | instantiate_me -- This is *the* place where ir_inst is consulted +instantiateAndFillInferResult orig ty inf_res = do { (wrap, rho) <- deeplyInstantiate orig ty ; co <- fillInferResult rho inf_res ; return (mkWpCastN co <.> wrap) } - | otherwise - = do { co <- fillInferResult ty inf_res - ; return (mkWpCastN co) } - fillInferResult :: TcType -> InferResult -> TcM TcCoercionN -- If wrap = fillInferResult t1 t2 -- => wrap :: t1 ~> t2 @@ -925,9 +912,8 @@ fillInferResult orig_ty (IR { ir_uniq = u, ir_lvl = res_lvl {- Note [Deep instantiation of InferResult] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In some cases we want to deeply instantiate before filling in -an InferResult, and in some cases not. That's why InferReult -has the ir_inst flag. +We now alwayd deeply instantiate before filling in InferResult, +and in some cases not: see #17775 ir_inst = True: deeply instantiate ---------------------------------- ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -770,9 +770,10 @@ zonkExpr env (HsApp x e1 e2) new_e2 <- zonkLExpr env e2 return (HsApp x new_e1 new_e2) -zonkExpr env (HsAppType x e t) +zonkExpr env (HsAppType ty e t) = do new_e <- zonkLExpr env e - return (HsAppType x new_e t) + new_ty <- zonkTcTypeToTypeX env ty + return (HsAppType new_ty new_e t) -- NB: the type is an HsType; can't zonk that! zonkExpr _ e@(HsRnBracketOut _ _ _) ===================================== testsuite/tests/typecheck/should_fail/tcfail007.stderr ===================================== @@ -1,5 +1,5 @@ -tcfail007.hs:3:14: error: +tcfail007.hs:3:15: error: • No instance for (Num Bool) arising from a use of ‘+’ • In the expression: x + 1 In an equation for ‘n’: ===================================== testsuite/tests/typecheck/should_fail/tcfail010.stderr ===================================== @@ -1,5 +1,5 @@ -tcfail010.hs:3:16: error: +tcfail010.hs:3:17: error: • No instance for (Num [a0]) arising from a use of ‘+’ • In the expression: z + 2 In the expression: \ (y : z) -> z + 2 ===================================== testsuite/tests/typecheck/should_fail/tcfail029.stderr ===================================== @@ -1,5 +1,5 @@ -tcfail029.hs:6:7: error: +tcfail029.hs:6:9: error: • No instance for (Ord Foo) arising from a use of ‘>’ • In the expression: x > Bar In an equation for ‘f’: f x = x > Bar ===================================== testsuite/tests/typecheck/should_fail/tcfail034.stderr ===================================== @@ -1,5 +1,5 @@ -tcfail034.hs:17:11: error: +tcfail034.hs:17:13: error: • Could not deduce (Integral a) arising from a use of ‘mod’ from the context: (Num a, Eq a) bound by the type signature for: ===================================== testsuite/tests/typecheck/should_fail/tcfail133.hs ===================================== @@ -73,7 +73,7 @@ foo = show $ add (One:@Zero) (One:@One) -- Add One One nr', AddDigit (Zero:@nr') One c, Show c -- -- ==> Add One One nr', AddDigit (Zero:@nr') One c, Show c --- +-- -- ==> Add One One (One:@One), AddDigit (Zero:@(One:@One)) One c, Show c -- -- ==> AddDigit (Zero:@(One:@One)) One c, Show c ===================================== testsuite/tests/typecheck/should_fail/tcfail143.stderr ===================================== @@ -1,5 +1,5 @@ -tcfail143.hs:29:6: error: +tcfail143.hs:29:9: error: • Couldn't match type ‘S Z’ with ‘Z’ arising from a functional dependency between: constraint ‘MinMax (S Z) Z Z Z’ arising from a use of ‘extend’ ===================================== testsuite/tests/typecheck/should_fail/tcfail208.stderr ===================================== @@ -1,5 +1,5 @@ -tcfail208.hs:4:10: error: +tcfail208.hs:4:19: error: • Could not deduce (Eq (m a)) arising from a use of ‘==’ from the context: (Monad m, Eq a) bound by the type signature for: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f39a0d86de843c105dc9cd4e0bd631176300d7f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f39a0d86de843c105dc9cd4e0bd631176300d7f7 You're receiving 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 14 00:47:16 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 13 Apr 2020 20:47:16 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Update comments/notes Message-ID: <5e950814af89e_6167e4e49b448290b@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: c9e7c782 by Andreas Klebinger at 2020-04-14T02:46:45+02:00 Update comments/notes Also use eqExpr for match_append_lit. - - - - - 2 changed files: - compiler/GHC/Core/Op/ConstantFold.hs - libraries/ghc-prim/GHC/CString.hs Changes: ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Types.Id import GHC.Types.Literal import GHC.Core.SimpleOpt ( exprIsLiteral_maybe, exprIsLambda_maybe , exprIsStrippableLiteral_maybe ) +import GHC.Core.FVs import PrimOp ( PrimOp(..), tagToEnumKey ) import TysWiredIn import TysPrim @@ -44,7 +45,7 @@ import GHC.Core.TyCon , isNewTyCon, unwrapNewTyCon_maybe, tyConDataCons , tyConFamilySize ) import GHC.Core.DataCon ( dataConTagZ, dataConTyCon, dataConWrapId, dataConWorkId ) -import GHC.Core.Utils ( cheapEqExpr, cheapEqExpr', exprIsHNF, exprType +import GHC.Core.Utils ( eqExpr, cheapEqExpr, cheapEqExpr', exprIsHNF, exprType , stripTicksTop, stripTicksTopT, mkTicks ) import GHC.Core.Unfold ( exprIsConApp_maybe ) import GHC.Core.Type @@ -69,7 +70,8 @@ import Data.Int import Data.Ratio import Data.Word - +import GHC.Types.Var.Set +import GHC.Types.Var.Env {- Note [Constant folding] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1467,11 +1469,20 @@ match_append_lit foldVariant _ id_unf _ `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 , unpk `hasKey` foldVariant - , cheapEqExpr' tickishFloatable c1 c2 - , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 - , c2Ticks <- stripTicksTopT tickishFloatable c2 + , pprTrace "match_append_lit" (ppr [ Type ty1 + , lit1 + , c1 + , e2 + ]) True , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 + , pprTraceIt "eqExpr" $ eqExpr + (mkInScopeSet (exprFreeVars c1 `unionVarSet` exprFreeVars c2)) + c1 c2 + , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 + , c2Ticks <- stripTicksTopT tickishFloatable c2 + , pprTrace "areLits?" (ppr c2Ticks) True + , pprTrace "Matched!" (ppr . show $ (s1,s2)) True = ASSERT( ty1 `eqType` ty2 ) Just $ mkTicks strTicks $ Var unpk `App` Type ty1 @@ -1492,6 +1503,9 @@ match_eq_string _ id_unf _ | unpk_key1 <- getUnique unpk1 , unpk_key2 <- getUnique unpk2 , unpk_key1 == unpk_key2 + -- For now we insist the literals have to agree in their encoding + -- to keep the rule simple. But we could check if the decoded strings + -- compare equal in here as well. , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 @@ -1506,30 +1520,39 @@ We start of with this userwritten code in haskell elem x "" -which we would like to transform into: +After optimization we would like the resul + +which we would like to transform this into an +expression semantically equivalent to: case x of + '<' -> True 'k' -> True - 'k' -> True - '_' -> True + 'n' -> True + 'o' -> True + ... + '>' -> True -For lists this would happen automatically via rules -associated with elem. However these do not fire for -string literals as we do not translate string literals -into actual lists for performance reasons. (At least -past a certain string size) +This is then either compiled to a binary search or a lookup table, so at +worst log(n) in complexity. -For string literals what happens in abensence of any -built in rules what would happen is: +For proper lists this happens via rules +associated with elem (elem/build). However these do not achieve the same +outcome when operating over string literals because we do not desugar them +to actual lists. See Note [String literals in GHC] for how strings are +desugared in general. + +For elem on string literals what would happen would be: 1) Start with: elem x "" 2) Desugar: elem x (unpackCString# ""#) -3) Apply "unpack" RULE in GHC.Base: [Phase 2 and earlier] +3) Apply "unpack" RULE in GHC.Base: [InitialPhase, Phase 2 and later]: elem x (build (unpackFoldrCString# ""#)) 3) Apply "build/elem" rule [Phase 2 and later] - + inline foldCString# [Phase 0]: + + inline foldCString# [Phase 0]. + Which gives this code: joinrec { unpack_a1ui (nh_ayh :: Int#) @@ -1547,24 +1570,32 @@ built in rules what would happen is: } Which is not *bad* we do not allocate, but we perform linear search -on the string. - -So instead we use match_elem to look for applications of elem to known -strings during all phases and transform them into case expressions -explicitly. Depending on the content of the string we then end up -with either a decision trees or lookup tables. - -Userwritten patterns of `elem x ""` will all -be caught during the initial phase since we match on both the -desugared form and the form after applying the "unpack" rule. -So it does not matter which rule ends up firing first. - -Should we get this pattern in a later pass it's a toin coss -if we get a case statement or linear search. But linear search -isn't bad enough to loose sleep over this scenario. - -The only exception is that we disable this rule for overly large -strings (>= 500 bytes). This avoid code size blow up if we check +on the string which being O(n) is in most cases worse. + +So what we do is: +a) Match on elem applications to known strings. +b) Transform them into a case via a builtin rule. + +However we want to match on applications before we hit phase 2 as +otherwise the "build/elem" rule might fire first and we end up +with linear search. + +For this reason we match on both, the desugared from and the form +after the "unpack" rule has been applied. This way it does not +matter if the unpack rule or the builtin rule fires first and we +can finish the whole transformation in the InitialPhase during which +"build/elem" is not yet active. + +Should the patterns we match on only emerge in later phases because +of inlining or other optimizations it's a toin coss which rule fires +first ("build/elem" or the one defined by match_elem) so we either +get a case statement or linear search. +But this is relatively rare and linear search isn't bad enough to +loose sleep over this scenario. Especially since there is no easy +way to change this. + +We do disable this optimiatzion for overly long strings strings +(>= 500 bytes). This avoids code size blow up if we check for many sparse values. -} ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -30,6 +30,64 @@ module GHC.CString ( import GHC.Types import GHC.Prim +{- +Note [String literals in GHC] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +String literals get quite a bit of special handling in GHC. This Note +summarises the moving parts. + +* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in + turn calls GHC.Core.Make.mkStringExprFS. + + The desugarer desugars the Haskell literal "foo" into Core + GHC.CString.unpackCString# "foo"# + where "foo"# is primitive string literal (of type Addr#). + + When the string cannot be encoded as a C string, we use UTF8: + GHC.CString.unpackCStringUtf8# "foo"# + +* The library module ghc-prim:GHC.CString has a bunch of functions that + work over primitive strings, including GHC.CString.unpackCString# + +* GHC.Core.Op.ConstantFold has some RULES that optimise treatment of + literal strings. These include things like: + + + Special handling of elem over string literals. + + Constant folding the desugared form of ("foo" ++ "bar") + into ("foobar") + + and more + +* GHC.Base has a number of regular rules for String literals. + + + a rule "eqString": (==) @String = eqString + where GHC.Base.eqString :: String -> String -> Bool + + ConstantFold has a RULE for eqString on literals: + eqString (Lit "foo"#) (Lit "bar"#) --> False + + This allows compile time evaluation of things like "foo" == "bar" + + + A bunch of rules to promote fusion: + + "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) + "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a + "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n + + And UTF8 variants of these rules. + +* We allow primitive (unlifted) literal strings to be top-level + bindings, breaking out usual rule. See GHC.Core + Note [Core top-level string literals] + +* TODO: There is work on a special code-gen path for top-level boxed strings + str :: [Char] + str = unpackCString# "foo"# + so that they can all share a common code pointer + + There is a WIP MR on gitlab for this: !3012 + +-} + ----------------------------------------------------------------------------- -- Unpacking C strings ----------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9e7c782bc1414f960d1116267c683da28f961df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9e7c782bc1414f960d1116267c683da28f961df You're receiving 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 14 01:21:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 21:21:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ticky-eventlog Message-ID: <5e95102ae1e0e_616713503ee04829994@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ticky-eventlog You're receiving 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 14 02:02:45 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:02:45 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e9519c56bbee_61673f8199536d944831791@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: a905c19a by Ben Gamari at 2020-04-13T22:01:50-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 9 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -57,6 +63,23 @@ startHeapProfTimer( void ) } } +void +stopTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = false; +#endif +} + +void +startTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = true; +#endif +} + + void initProfTimer( void ) { @@ -83,6 +106,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (do_ticky_sample_ticks) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -332,6 +332,13 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) ioManagerStart(); #endif +#if defined(TICKY_TICKY) && defined(TRACING) + /* Dump the ticky counter definitions */ + if (RtsFlags.TraceFlags.ticky) { + startTickySampleTimer(); + } +#endif + /* Record initialization times */ stat_endInit(); } @@ -419,6 +426,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + postTickyCounterDefs(ticky_entry_ctrs); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r") + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,5 @@ printRegisteredCounterInfo (FILE *tf) } } + #endif /* TICKY_TICKY */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -120,7 +120,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -488,6 +490,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1460,6 +1470,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -170,6 +170,11 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDef(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, ===================================== rts/sm/GC.c ===================================== @@ -858,6 +858,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + postTickyCounterSamples(ticky_entry_ctrs); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a905c19a74e5aa21d97fc761bc6b66f4ccbed3dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a905c19a74e5aa21d97fc761bc6b66f4ccbed3dc You're receiving 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 14 02:04:00 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:04:00 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] 9 commits: testsuite: Move no_lint to the top level, tweak hie002 Message-ID: <5e951a103cf81_616776d1c74483195b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - a643a844 by Ben Gamari at 2020-04-13T22:03:45-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 30 changed files: - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/utils/Binary.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/extending_ghc.rst - docs/users_guide/exts/existential_quantification.rst - + docs/users_guide/exts/field_selectors_and_type_applications.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/rank_polymorphism.rst - docs/users_guide/exts/records.rst - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Packages.hs - includes/rts/EventLogFormat.h - includes/rts/Flags.h - libraries/base/Control/Category.hs - libraries/base/GHC/Desugar.hs - rts/Proftimer.c - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a905c19a74e5aa21d97fc761bc6b66f4ccbed3dc...a643a844663046e4e27e72d8b490a18f4db481b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a905c19a74e5aa21d97fc761bc6b66f4ccbed3dc...a643a844663046e4e27e72d8b490a18f4db481b2 You're receiving 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 14 02:19:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:19:36 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e951db83e805_61673f8199536d9448335be@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: affd6197 by Ben Gamari at 2020-04-13T22:19:22-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 9 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -57,6 +63,23 @@ startHeapProfTimer( void ) } } +void +stopTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = false; +#endif +} + +void +startTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = true; +#endif +} + + void initProfTimer( void ) { @@ -83,6 +106,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (do_ticky_sample_ticks) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -332,6 +332,13 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) ioManagerStart(); #endif +#if defined(TICKY_TICKY) && defined(TRACING) + /* Dump the ticky counter definitions */ + if (RtsFlags.TraceFlags.ticky) { + startTickySampleTimer(); + } +#endif + /* Record initialization times */ stat_endInit(); } @@ -419,6 +426,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + postTickyCounterDefs(ticky_entry_ctrs); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,5 @@ printRegisteredCounterInfo (FILE *tf) } } + #endif /* TICKY_TICKY */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,6 +168,11 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDef(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, ===================================== rts/sm/GC.c ===================================== @@ -858,6 +858,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + postTickyCounterSamples(ticky_entry_ctrs); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/affd619784fb1e609cd33e87b543a838a806da22 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/affd619784fb1e609cd33e87b543a838a806da22 You're receiving 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 14 02:35:12 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:35:12 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95216082032_6167e4e49b4483912c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: c6648c95 by Ben Gamari at 2020-04-13T22:35:04-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 10 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -57,6 +63,23 @@ startHeapProfTimer( void ) } } +void +stopTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = false; +#endif +} + +void +startTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = true; +#endif +} + + void initProfTimer( void ) { @@ -83,6 +106,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (do_ticky_sample_ticks) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -332,6 +332,13 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) ioManagerStart(); #endif +#if defined(TICKY_TICKY) && defined(TRACING) + /* Dump the ticky counter definitions */ + if (RtsFlags.TraceFlags.ticky) { + startTickySampleTimer(); + } +#endif + /* Record initialization times */ stat_endInit(); } @@ -419,6 +426,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + postTickyCounterDefs(ticky_entry_ctrs); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,5 @@ printRegisteredCounterInfo (FILE *tf) } } + #endif /* TICKY_TICKY */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,11 +168,21 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDef(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -52,6 +52,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "eventlog/EventLog.h" #include // for memset() #include @@ -858,6 +859,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + postTickyCounterSamples(ticky_entry_ctrs); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6648c95ae046e25e22f84b3a890c204a55dbbff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6648c95ae046e25e22f84b3a890c204a55dbbff You're receiving 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 14 02:41:42 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:41:42 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e9522e668e06_6167e4e49b4484037d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: ce441b10 by Ben Gamari at 2020-04-13T22:41:30-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -57,6 +63,23 @@ startHeapProfTimer( void ) } } +void +stopTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = false; +#endif +} + +void +startTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = true; +#endif +} + + void initProfTimer( void ) { @@ -83,6 +106,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (do_ticky_sample_ticks) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -332,6 +332,13 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) ioManagerStart(); #endif +#if defined(TICKY_TICKY) && defined(TRACING) + /* Dump the ticky counter definitions */ + if (RtsFlags.TraceFlags.ticky) { + startTickySampleTimer(); + } +#endif + /* Record initialization times */ stat_endInit(); } @@ -419,6 +426,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(ticky_entry_ctrs); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterSamples() + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,11 +168,21 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDef(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -52,6 +52,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +859,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce441b10174b76233accf31bc963617b76599cc3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce441b10174b76233accf31bc963617b76599cc3 You're receiving 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 14 02:45:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:45:23 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e9523c378552_61673f8198ee100c4841389@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: a027e9e3 by Ben Gamari at 2020-04-13T22:44:28-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -57,6 +63,23 @@ startHeapProfTimer( void ) } } +void +stopTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = false; +#endif +} + +void +startTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = true; +#endif +} + + void initProfTimer( void ) { @@ -83,6 +106,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (do_ticky_sample_ticks) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -332,6 +332,13 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) ioManagerStart(); #endif +#if defined(TICKY_TICKY) && defined(TRACING) + /* Dump the ticky counter definitions */ + if (RtsFlags.TraceFlags.ticky) { + startTickySampleTimer(); + } +#endif + /* Record initialization times */ stat_endInit(); } @@ -419,6 +426,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(ticky_entry_ctrs); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *p) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,11 +168,21 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDef(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -52,6 +52,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +859,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a027e9e337017d81beec7587ed48af6d7562093d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a027e9e337017d81beec7587ed48af6d7562093d You're receiving 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 14 02:47:19 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:47:19 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95243767fe8_61673f8198ee100c4841779@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 47b117e6 by Ben Gamari at 2020-04-13T22:47:02-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -57,6 +63,23 @@ startHeapProfTimer( void ) } } +void +stopTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = false; +#endif +} + +void +startTickySampleTimer( void ) +{ +#if defined(PROFILING) + do_ticky_sample_ticks = true; +#endif +} + + void initProfTimer( void ) { @@ -83,6 +106,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (do_ticky_sample_ticks) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -332,6 +332,13 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) ioManagerStart(); #endif +#if defined(TICKY_TICKY) && defined(TRACING) + /* Dump the ticky counter definitions */ + if (RtsFlags.TraceFlags.ticky) { + startTickySampleTimer(); + } +#endif + /* Record initialization times */ stat_endInit(); } @@ -419,6 +426,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(ticky_entry_ctrs); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs() +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples() +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,11 +168,21 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -52,6 +52,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +859,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47b117e67421e9d93032b6ce20c9bfa34e1834d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47b117e67421e9d93032b6ce20c9bfa34e1834d3 You're receiving 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 14 02:51:58 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:51:58 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95254e736bb_6167136dfb9c48421a2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: c2fda821 by Ben Gamari at 2020-04-13T22:51:44-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs() +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples() +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,11 +168,21 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -52,6 +52,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +859,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2fda821609af53108aa5f334a8feccc5c3bd4ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2fda821609af53108aa5f334a8feccc5c3bd4ef You're receiving 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 14 02:53:07 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:53:07 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95259397529_616776d1c74484258c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: d45e8630 by Ben Gamari at 2020-04-13T22:52:54-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs() +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterDef(p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples() +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = ticky_entry_ctrs; p != NULL; p = p->link) { + postTickyCounterSample(p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -168,11 +168,21 @@ void postProfSampleCostCentre(Capability *cap, void postProfBegin(void); #endif /* PROFILING */ +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSample(StgEntCounter *p); +#endif /* TICKY_TICKY */ + void postConcUpdRemSetFlush(Capability *cap); void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d45e86305cb400ce384689d7e1a414002db4b27d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d45e86305cb400ce384689d7e1a414002db4b27d You're receiving 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 14 02:56:58 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:56:58 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95267a8e0c8_6167e4e49b44842988@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: dec46d22 by Ben Gamari at 2020-04-13T22:56:41-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dec46d223f70f3dfc53d6394b6fc18070d7d9be3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dec46d223f70f3dfc53d6394b6fc18070d7d9be3 You're receiving 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 14 02:58:09 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 22:58:09 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e9526c1878a9_6167136dfb9c4843379@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: d3935e9c by Ben Gamari at 2020-04-13T22:58:01-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -46,6 +46,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +378,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3935e9c8ba380517114caac675e76456efc739e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3935e9c8ba380517114caac675e76456efc739e You're receiving 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 14 03:19:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 23:19:47 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e952bd37fd98_61673f8198ee100c48443b5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: c2d4d4f7 by Ben Gamari at 2020-04-13T23:19:39-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2d4d4f74ff295e541f79fd41cc0689b9e5955af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2d4d4f74ff295e541f79fd41cc0689b9e5955af You're receiving 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 14 03:20:25 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 23:20:25 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e952bf9e4972_61677c82e0c484477f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 26ef2fe8 by Ben Gamari at 2020-04-13T23:20:15-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) && defined(TRACING) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,15 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ + postTickyCounterDefs(ticky_entry_ctrs); +} + +void emitTickyCounterSamples() +{ + postTickyCounterSamples(ticky_entry_ctrs); +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26ef2fe8ba583ffe178bf168c69f3616852b9be1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26ef2fe8ba583ffe178bf168c69f3616852b9be1 You're receiving 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 14 03:27:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 23:27:30 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e952da214176_616713503ee048453e4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: ef311a76 by Ben Gamari at 2020-04-13T23:27:10-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) && defined(TRACING) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1459,6 +1469,52 @@ void postProfSampleCostCentre(Capability *cap, RELEASE_LOCK(&eventBufMutex); } + +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + // This event is output at the start of profiling so the tick interval can // be reported. Once the tick interval is reported the total executation time // can be calculuated from how many samples there are. ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef311a760248cbeed8ad627999796008ecfe2f7b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef311a760248cbeed8ad627999796008ecfe2f7b You're receiving 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 14 03:48:09 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 23:48:09 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e953279cc148_6167134ebbc44846312@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 2b06aba7 by Ben Gamari at 2020-04-13T23:47:47-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_ENTRY_COUNTER_DEF 210 +#define EVENT_TICKY_ENTRY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) && defined(TRACING) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_ENTRY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_ENTRY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,51 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_ENTRY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_ENTRY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_ENTRY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2b06aba76f1b8554ab6c53d61cb42ca13ecc1b22 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2b06aba76f1b8554ab6c53d61cb42ca13ecc1b22 You're receiving 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 14 03:50:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 23:50:36 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95330cc1480_61677c82e0c48467fc@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 2ebe1efb by Ben Gamari at 2020-04-13T23:50:28-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_ENTRY_COUNTER_DEF 210 +#define EVENT_TICKY_ENTRY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +#if defined(TICKY_TICKY) && defined(TRACING) +static bool do_ticky_sample_ticks = false; // enable dumping of ticky counters to eventlog +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_ENTRY_COUNTER_DEF] = "Ticky-ticky entry counter definition", + [EVENT_TICKY_ENTRY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_ENTRY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_ENTRY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,51 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_ENTRY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_ENTRY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_ENTRY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ebe1efb2675ba8aef3e566421e162b801d96f7b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ebe1efb2675ba8aef3e566421e162b801d96f7b You're receiving 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 14 03:52:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 13 Apr 2020 23:52:44 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5e95338ccf852_61673f8198ee100c48471df@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 8280f0d8 by Ben Gamari at 2020-04-13T23:52:33-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -194,12 +194,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_ENTRY_COUNTER_DEF 210 +#define EVENT_TICKY_ENTRY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +// Sampling of Ticky-Ticky profiler to eventlog +#if defined(TICKY_TICKY) && defined(TRACING) +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -385,6 +386,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1790,6 +1794,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2232,6 +2241,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -419,6 +419,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_ENTRY_COUNTER_DEF] = "Ticky-ticky entry counter definition", + [EVENT_TICKY_ENTRY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_ENTRY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_ENTRY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,51 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postPayloadSize(eb, len); + postEventHeader(eb, EVENT_TICKY_ENTRY_COUNTER_DEF); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + ensureRoomForEvent(eb, EVENT_TICKY_ENTRY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_ENTRY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -858,6 +860,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8280f0d885d68bfc4468e4e127e978c96d1bfad1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8280f0d885d68bfc4468e4e127e978c96d1bfad1 You're receiving 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 14 04:56:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 14 Apr 2020 00:56:32 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/lower-tc-tracing-cost Message-ID: <5e9542807818c_6167134ebbc448485bd@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/lower-tc-tracing-cost You're receiving 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 14 05:16:18 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 14 Apr 2020 01:16:18 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] typecheck: Avoid unnecessary tracing allocations Message-ID: <5e9547222f256_6167e4e49b4485036c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: 16c4bbf9 by Ben Gamari at 2020-04-14T01:16:08-04:00 typecheck: Avoid unnecessary tracing allocations While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. - - - - - 1 changed file: - compiler/GHC/Tc/Utils/Monad.hs Changes: ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,6 +490,7 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- Note [INLINE trace{Tc,Rn}] whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag @@ -665,39 +666,47 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE trace{Tc,Rn}] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- Note [INLINE trace{Tc,Rn}] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- Note [INLINE trace{Tc,Rn}] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledOptTraceTcRn #-} -- Note [INLINE trace{Tc,Rn}] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- Note [INLINE trace{Tc,Rn}] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- Note [INLINE trace{TcRn}] -- | Unconditionally dump some trace output -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16c4bbf9bc36b247265029fb63afba28c7810835 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16c4bbf9bc36b247265029fb63afba28c7810835 You're receiving 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 14 05:19:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 14 Apr 2020 01:19:28 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] typecheck: Avoid unnecessary tracing allocations Message-ID: <5e9547e0701a2_616713503ee04850790@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: 815f0124 by Ben Gamari at 2020-04-14T01:19:21-04:00 typecheck: Avoid unnecessary tracing allocations While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. - - - - - 1 changed file: - compiler/GHC/Tc/Utils/Monad.hs Changes: ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,6 +490,7 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- Note [INLINE trace{Tc,Rn}] whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag @@ -665,39 +666,47 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE trace{Tc,Rn}] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- Note [INLINE trace{Tc,Rn}] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- Note [INLINE trace{Tc,Rn}] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledTraceOptTcRn #-} -- Note [INLINE trace{Tc,Rn}] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- Note [INLINE trace{Tc,Rn}] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- Note [INLINE trace{TcRn}] -- | Unconditionally dump some trace output -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/815f0124db8d2fc0517d888a1bb5f02c58118408 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/815f0124db8d2fc0517d888a1bb5f02c58118408 You're receiving 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 14 08:31:47 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 14 Apr 2020 04:31:47 -0400 Subject: [Git][ghc/ghc][wip/T17775] Revert accidental haddock change Message-ID: <5e9574f3638ef_61673f8199536d9448633f1@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 1c64261a by Ömer Sinan Ağacan at 2020-04-14T11:31:35+03:00 Revert accidental haddock change - - - - - 1 changed file: - utils/haddock Changes: ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 65f22afa9e66195baa6b7d44369e2b23cd8f77d2 +Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c64261abb387fc7a5accbb2e41c1ac61b80803c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c64261abb387fc7a5accbb2e41c1ac61b80803c You're receiving 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 14 11:38:26 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 14 Apr 2020 07:38:26 -0400 Subject: [Git][ghc/ghc][wip/T18052] Fix #18052 by using pprPrefixOcc in more places Message-ID: <5e95a0b264c0a_6167134ebbc44907296@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18052 at Glasgow Haskell Compiler / GHC Commits: 6d130940 by Ryan Scott at 2020-04-14T07:37:55-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - 9 changed files: - compiler/GHC/Core/Ppr.hs - compiler/GHC/Tc/Module.hs - + testsuite/tests/ghci/should_fail/T18052b.script - + testsuite/tests/ghci/should_fail/T18052b.stderr - testsuite/tests/ghci/should_fail/all.T - testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr - + testsuite/tests/printer/T18052a.hs - + testsuite/tests/printer/T18052a.stderr - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -123,11 +123,13 @@ ppr_binding ann (val_bdr, expr) , pp_bind ] where + pp_val_bdr = pprPrefixOcc val_bdr + pp_bind = case bndrIsJoin_maybe val_bdr of Nothing -> pp_normal_bind Just ar -> pp_join_bind ar - pp_normal_bind = hang (ppr val_bdr) 2 (equals <+> pprCoreExpr expr) + pp_normal_bind = hang pp_val_bdr 2 (equals <+> pprCoreExpr expr) -- For a join point of join arity n, we want to print j = \x1 ... xn -> e -- as "j x1 ... xn = e" to differentiate when a join point returns a @@ -135,7 +137,7 @@ ppr_binding ann (val_bdr, expr) -- an n-argument function). pp_join_bind join_arity | bndrs `lengthAtLeast` join_arity - = hang (ppr val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) + = hang (pp_val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) 2 (equals <+> pprCoreExpr rhs) | otherwise -- Yikes! A join-binding with too few lambda -- Lint will complain, but we don't want to crash @@ -164,8 +166,10 @@ ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc -- an atomic value (e.g. function args) ppr_expr add_par (Var name) - | isJoinId name = add_par ((text "jump") <+> ppr name) - | otherwise = ppr name + | isJoinId name = add_par ((text "jump") <+> pp_name) + | otherwise = pp_name + where + pp_name = pprPrefixOcc name ppr_expr add_par (Type ty) = add_par (text "TYPE:" <+> ppr ty) -- Weird ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> ppr co) ppr_expr add_par (Lit lit) = pprLiteral add_par lit @@ -429,7 +433,7 @@ pprKindedTyVarBndr tyvar -- pprIdBndr does *not* print the type -- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness pprIdBndr :: Id -> SDoc -pprIdBndr id = ppr id <+> pprIdBndrInfo (idInfo id) +pprIdBndr id = pprPrefixOcc id <+> pprIdBndrInfo (idInfo id) pprIdBndrInfo :: IdInfo -> SDoc pprIdBndrInfo info ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2122,7 +2122,7 @@ tcRnStmt hsc_env rdr_stmt } where bad_unboxed id = addErr (sep [text "GHCi can't bind a variable of unlifted type:", - nest 2 (ppr id <+> dcolon <+> ppr (idType id))]) + nest 2 (pprPrefixOcc id <+> dcolon <+> ppr (idType id))]) {- -------------------------------------------------------------------------- @@ -2903,7 +2903,7 @@ ppr_types debug type_env -- etc are suppressed (unless -dppr-debug), -- because they appear elsewhere - ppr_sig id = hang (ppr id <+> dcolon) 2 (ppr (tidyTopType (idType id))) + ppr_sig id = hang (pprPrefixOcc id <+> dcolon) 2 (ppr (tidyTopType (idType id))) ppr_tycons :: Bool -> [FamInst] -> TypeEnv -> SDoc ppr_tycons debug fam_insts type_env @@ -2921,7 +2921,7 @@ ppr_tycons debug fam_insts type_env | otherwise = isExternalName (tyConName tycon) && not (tycon `elem` fi_tycons) ppr_tc tc - = vcat [ hang (ppr (tyConFlavour tc) <+> ppr tc + = vcat [ hang (ppr (tyConFlavour tc) <+> pprPrefixOcc (tyConName tc) <> braces (ppr (tyConArity tc)) <+> dcolon) 2 (ppr (tidyTopType (tyConKind tc))) , nest 2 $ @@ -2955,7 +2955,7 @@ ppr_patsyns type_env = ppr_things "PATTERN SYNONYMS" ppr_ps (typeEnvPatSyns type_env) where - ppr_ps ps = ppr ps <+> dcolon <+> pprPatSynType ps + ppr_ps ps = pprPrefixOcc ps <+> dcolon <+> pprPatSynType ps ppr_insts :: [ClsInst] -> SDoc ppr_insts ispecs ===================================== testsuite/tests/ghci/should_fail/T18052b.script ===================================== @@ -0,0 +1,2 @@ +:set -XMagicHash +let (%%%) = 1# ===================================== testsuite/tests/ghci/should_fail/T18052b.stderr ===================================== @@ -0,0 +1,3 @@ + +:1:1: error: + GHCi can't bind a variable of unlifted type: (%%%) :: GHC.Prim.Int# ===================================== testsuite/tests/ghci/should_fail/all.T ===================================== @@ -3,3 +3,4 @@ test('T10549a', [], ghci_script, ['T10549a.script']) test('T15055', normalise_version('ghc'), ghci_script, ['T15055.script']) test('T16013', [], ghci_script, ['T16013.script']) test('T16287', [], ghci_script, ['T16287.script']) +test('T18052b', [], ghci_script, ['T18052b.script']) ===================================== testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr ===================================== @@ -1,28 +1,28 @@ TYPE SIGNATURES - !! :: forall {a}. [a] -> Int -> a - $ :: forall {a} {b}. (a -> b) -> a -> b - $! :: forall {a} {b}. (a -> b) -> a -> b - && :: Bool -> Bool -> Bool - * :: forall {a}. Num a => a -> a -> a - ** :: forall {a}. Floating a => a -> a -> a - + :: forall {a}. Num a => a -> a -> a - ++ :: forall {a}. [a] -> [a] -> [a] - - :: forall {a}. Num a => a -> a -> a - . :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c - / :: forall {a}. Fractional a => a -> a -> a - /= :: forall {a}. Eq a => a -> a -> Bool - < :: forall {a}. Ord a => a -> a -> Bool - <= :: forall {a}. Ord a => a -> a -> Bool - =<< :: + (!!) :: forall {a}. [a] -> Int -> a + ($) :: forall {a} {b}. (a -> b) -> a -> b + ($!) :: forall {a} {b}. (a -> b) -> a -> b + (&&) :: Bool -> Bool -> Bool + (*) :: forall {a}. Num a => a -> a -> a + (**) :: forall {a}. Floating a => a -> a -> a + (+) :: forall {a}. Num a => a -> a -> a + (++) :: forall {a}. [a] -> [a] -> [a] + (-) :: forall {a}. Num a => a -> a -> a + (.) :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c + (/) :: forall {a}. Fractional a => a -> a -> a + (/=) :: forall {a}. Eq a => a -> a -> Bool + (<) :: forall {a}. Ord a => a -> a -> Bool + (<=) :: forall {a}. Ord a => a -> a -> Bool + (=<<) :: forall {m :: * -> *} {a} {b}. Monad m => (a -> m b) -> m a -> m b - == :: forall {a}. Eq a => a -> a -> Bool - > :: forall {a}. Ord a => a -> a -> Bool - >= :: forall {a}. Ord a => a -> a -> Bool - >> :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b - >>= :: + (==) :: forall {a}. Eq a => a -> a -> Bool + (>) :: forall {a}. Ord a => a -> a -> Bool + (>=) :: forall {a}. Ord a => a -> a -> Bool + (>>) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b + (>>=) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> (a -> m b) -> m b - ^ :: forall {b} {a}. (Integral b, Num a) => a -> b -> a - ^^ :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a + (^) :: forall {b} {a}. (Integral b, Num a) => a -> b -> a + (^^) :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a abs :: forall {a}. Num a => a -> a acos :: forall {a}. Floating a => a -> a acosh :: forall {a}. Floating a => a -> a @@ -234,7 +234,7 @@ TYPE SIGNATURES zipWith3 :: forall {a} {b} {c} {d}. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] - || :: Bool -> Bool -> Bool + (||) :: Bool -> Bool -> Bool Dependent modules: [] -Dependent packages: [base-4.13.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeOperators #-} +module T18052a where + +(+++) = (++) +pattern x :||: y = (x,y) +type (^^^) = Either +data (&&&) ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -0,0 +1,42 @@ +TYPE SIGNATURES + (+++) :: forall {a}. [a] -> [a] -> [a] +TYPE CONSTRUCTORS + data type (&&&){0} :: * + type synonym (^^^){0} :: * -> * -> * +PATTERN SYNONYMS + (:||:) :: forall {a} {b}. a -> b -> (a, b) +Dependent modules: [] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 18, types: 53, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) +[GblId, Arity=2, Unf=OtherCon []] +T18052a.$b:||: = GHC.Tuple.(,) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +(+++) :: forall {a}. [a] -> [a] -> [a] +[GblId] +(+++) = (++) + +-- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +T18052a.$m:||: + :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. + (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r +[GblId, Arity=3, Unf=OtherCon []] +T18052a.$m:||: + = \ (@(rep :: GHC.Types.RuntimeRep)) + (@(r :: TYPE rep)) + (@a) + (@b) + (scrut :: (a, b)) + (cont :: a -> b -> r) + _ [Occ=Dead] -> + case scrut of { (x, y) -> cont x y } + + + ===================================== testsuite/tests/printer/all.T ===================================== @@ -57,3 +57,5 @@ test('T14306', ignore_stderr, makefile_test, ['T14306']) test('T14343', normal, compile_fail, ['']) test('T14343b', normal, compile_fail, ['']) test('T15761', normal, compile_fail, ['']) +test('T18052a', normal, compile, + ['-ddump-simpl -ddump-types -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d13094019f6dab9c3af834ed543a699b4ed710e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d13094019f6dab9c3af834ed543a699b4ed710e You're receiving 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 14 11:55:31 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 07:55:31 -0400 Subject: [Git][ghc/ghc][master] Change zipWith to zipWithEqual in a few places Message-ID: <5e95a4b3379c7_616776d1c744910617@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 12 changed files: - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/Zonk.hs Changes: ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -559,8 +559,9 @@ opt_univ env sym prov role oty1 oty2 PluginProv _ -> prov ------------- -opt_transList :: InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] -opt_transList is = zipWith (opt_trans is) +opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] +opt_transList is = zipWithEqual "opt_transList" (opt_trans is) + -- The input lists must have identical length. opt_trans :: InScopeSet -> NormalCo -> NormalCo -> NormalCo opt_trans is co1 co2 @@ -659,14 +660,12 @@ opt_trans_rule is in_co1@(AppCo co1a co1b) in_co2@(AppCo co2a co2b) -- Eta rules opt_trans_rule is co1@(TyConAppCo r tc cos1) co2 | Just cos2 <- etaTyConAppCo_maybe tc co2 - = ASSERT( cos1 `equalLength` cos2 ) - fireTransRule "EtaCompL" co1 co2 $ + = fireTransRule "EtaCompL" co1 co2 $ mkTyConAppCo r tc (opt_transList is cos1 cos2) opt_trans_rule is co1 co2@(TyConAppCo r tc cos2) | Just cos1 <- etaTyConAppCo_maybe tc co1 - = ASSERT( cos1 `equalLength` cos2 ) - fireTransRule "EtaCompR" co1 co2 $ + = fireTransRule "EtaCompR" co1 co2 $ mkTyConAppCo r tc (opt_transList is cos1 cos2) opt_trans_rule is co1@(AppCo co1a co1b) co2 ===================================== compiler/GHC/Core/Op/FloatIn.hs ===================================== @@ -169,7 +169,9 @@ fiExpr platform to_drop ann_expr@(_,AnnApp {}) = wrapFloats drop_here $ wrapFloats extra_drop $ mkTicks ticks $ mkApps (fiExpr platform fun_drop ann_fun) - (zipWith (fiExpr platform) arg_drops ann_args) + (zipWithEqual "fiExpr" (fiExpr platform) arg_drops ann_args) + -- use zipWithEqual, we should have + -- length ann_args = length arg_fvs = length arg_drops where (ann_fun, ann_args, ticks) = collectAnnArgsTicks tickishFloatable ann_expr fun_ty = exprType (deAnnotate ann_fun) @@ -466,7 +468,8 @@ fiExpr platform to_drop (_, AnnCase scrut case_bndr ty alts) = wrapFloats drop_here1 $ wrapFloats drop_here2 $ Case (fiExpr platform scrut_drops scrut) case_bndr ty - (zipWith fi_alt alts_drops_s alts) + (zipWithEqual "fiExpr" fi_alt alts_drops_s alts) + -- use zipWithEqual, we should have length alts_drops_s = length alts where -- Float into the scrut and alts-considered-together just like App [drop_here1, scrut_drops, alts_drops] ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -1319,7 +1319,7 @@ mkLoopBreakerNodes :: OccEnv -> TopLevelFlag -- d) adjust each RHS's usage details according to -- the binder's (new) shotness and join-point-hood mkLoopBreakerNodes env lvl bndr_set body_uds details_s - = (final_uds, zipWith mk_lb_node details_s bndrs') + = (final_uds, zipWithEqual "mkLoopBreakerNodes" mk_lb_node details_s bndrs') where (final_uds, bndrs') = tagRecBinders lvl body_uds ===================================== compiler/GHC/Core/Op/SpecConstr.hs ===================================== @@ -1311,7 +1311,9 @@ scExpr' env (Let (Rec prs) body) -- See Note [Local recursive groups] ; let all_usg = spec_usg `combineUsage` body_usg -- Note [spec_usg includes rhs_usg] - bind' = Rec (concat (zipWith ruleInfoBinds rhs_infos specs)) + bind' = Rec (concat (zipWithEqual "scExpr'" ruleInfoBinds rhs_infos specs)) + -- zipWithEqual: length of returned [SpecInfo] + -- should be the same as incoming [RhsInfo] ; return (all_usg { scu_calls = scu_calls all_usg `delVarEnvList` bndrs' }, Let bind' body') } ===================================== compiler/GHC/Core/Op/WorkWrap/Lib.hs ===================================== @@ -653,8 +653,7 @@ nop_fn body = body addDataConStrictness :: DataCon -> [Demand] -> [Demand] -- See Note [Add demands for strict constructors] addDataConStrictness con ds - = ASSERT2( equalLength strs ds, ppr con $$ ppr strs $$ ppr ds ) - zipWith add ds strs + = zipWithEqual "addDataConStrictness" add ds strs where strs = dataConRepStrictness con add dmd str | isMarkedStrict str = strictifyDmd dmd ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -788,7 +788,7 @@ dsSyntaxExpr (SyntaxExprTc { syn_expr = expr = do { fun <- dsExpr expr ; core_arg_wraps <- mapM dsHsWrapper arg_wraps ; core_res_wrap <- dsHsWrapper res_wrap - ; let wrapped_args = zipWith ($) core_arg_wraps arg_exprs + ; let wrapped_args = zipWithEqual "dsSyntaxExpr" ($) core_arg_wraps arg_exprs ; dsWhenNoErrs (zipWithM_ dsNoLevPolyExpr wrapped_args [ mk_doc n | n <- [1..] ]) (\_ -> core_res_wrap (mkApps fun wrapped_args)) } where ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -285,7 +285,7 @@ d1 `withRolesFrom` d2 = d1 { ifRoles = mergeRoles roles1 roles2 } | otherwise = d1 where - mergeRoles roles1 roles2 = zipWith max roles1 roles2 + mergeRoles roles1 roles2 = zipWithEqual "mergeRoles" max roles1 roles2 isRepInjectiveIfaceDecl :: IfaceDecl -> Bool isRepInjectiveIfaceDecl IfaceData{ ifCons = IfDataTyCon _ } = True ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -606,7 +606,7 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv (Just BreakInfo{..}) = do syncOccs mbVs ocs = unzip3 $ catMaybes $ joinOccs mbVs ocs where joinOccs :: [Maybe (a,b)] -> [c] -> [Maybe (a,b,c)] - joinOccs = zipWith joinOcc + joinOccs = zipWithEqual "bindLocalsAtBreakpoint" joinOcc joinOcc mbV oc = (\(a,b) c -> (a,b,c)) <$> mbV <*> pure oc rttiEnvironment :: HscEnv -> IO HscEnv ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -1183,7 +1183,7 @@ gen_Show_binds get_fixity loc tycon where nm = wrapOpParens (unpackFS l) - show_args = zipWith show_arg bs_needed arg_tys + show_args = zipWithEqual "gen_Show_binds" show_arg bs_needed arg_tys (show_arg1:show_arg2:_) = show_args show_prefix_args = intersperse (nlHsVar showSpace_RDR) show_args ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -2053,11 +2053,14 @@ expandSynonymsToMatch ty1 ty2 = (ty1_ret, ty2_ret) (t1, t2) go (TyConApp tc1 tys1) (TyConApp tc2 tys2) - | tc1 == tc2 = + | tc1 == tc2 + , tys1 `equalLength` tys2 = -- Type constructors are same. They may be synonyms, but we don't - -- expand further. + -- expand further. The lengths of tys1 and tys2 must be equal; + -- for example, with type S a = a, we don't want + -- to zip (S Monad Int) and (S Bool). let (tys1', tys2') = - unzip (zipWith (\ty1 ty2 -> go ty1 ty2) tys1 tys2) + unzip (zipWithEqual "expandSynonymsToMatch" go tys1 tys2) in (TyConApp tc1 tys1', TyConApp tc2 tys2') go (AppTy t1_1 t1_2) (AppTy t2_1 t2_2) = ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -707,7 +707,7 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap -- Ensure that every old binder of type `b` is linked up with its -- new binder which should have type `n b` -- See Note [GroupStmt binder map] in GHC.Hs.Expr - n_bndr_ids = zipWith mk_n_bndr n_bndr_names bndr_ids + n_bndr_ids = zipWithEqual "tcMcStmt" mk_n_bndr n_bndr_names bndr_ids bindersMap' = bndr_ids `zip` n_bndr_ids -- Type check the thing in the environment with ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -1226,7 +1226,8 @@ zonkStmt env _zBody (ApplicativeStmt body_ty args mb_join) zonk_args env args = do { (env1, new_args_rev) <- zonk_args_rev env (reverse args) ; (env2, new_pats) <- zonkPats env1 (map get_pat args) - ; return (env2, zipWith replace_pat new_pats (reverse new_args_rev)) } + ; return (env2, zipWithEqual "zonkStmt" replace_pat + new_pats (reverse new_args_rev)) } -- these need to go backward, because if any operators are higher-rank, -- later operators may introduce skolems that are in scope for earlier View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0da186c1b5a47e08e91c1c674d46c040c83932fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0da186c1b5a47e08e91c1c674d46c040c83932fc You're receiving 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 14 11:56:04 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 07:56:04 -0400 Subject: [Git][ghc/ghc][master] Small change to the windows ticker. Message-ID: <5e95a4d5a3_616713503ee049134b9@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - 1 changed file: - rts/win32/Ticker.c Changes: ===================================== rts/win32/Ticker.c ===================================== @@ -30,6 +30,12 @@ static VOID CALLBACK tick_callback( // be very useful for profiling with a max usable resolution of // 15ms. Unfortunately we don't have anything better. +// Update as of 2020-04-02: +// It seems we can get somewhat reliable resolution even for intervals +// at 1ms which had an average error of <5%. +// This seems to be the case starting at some point during the +// Windows 7 lifetime and any newer versions of windows. + void initTicker (Time interval, TickProc handle_tick) { @@ -53,7 +59,7 @@ startTicker(void) tick_callback, 0, 0, - TimeToUS(tick_interval) / 1000, // ms + TimeToMS(tick_interval), // ms WT_EXECUTEINTIMERTHREAD); if (r == 0) { sysErrorBelch("CreateTimerQueueTimer"); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/074c1ccd3f8c3fcab117e336316173e8e869230a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/074c1ccd3f8c3fcab117e336316173e8e869230a You're receiving 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 14 11:56:47 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 07:56:47 -0400 Subject: [Git][ghc/ghc][master] hadrian: get rid of unnecessary levels of nesting in source-dist Message-ID: <5e95a4ffdfc3_61677c82e0c49162dc@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - 2 changed files: - hadrian/src/Builder.hs - hadrian/src/Rules/SourceDist.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -285,6 +285,7 @@ instance H.Builder Builder where unit $ cmd [Cwd output] [path] buildArgs unit $ cmd [Cwd output] [path] buildArgs + Tar _ -> cmd buildOptions echo [path] buildArgs _ -> cmd echo [path] buildArgs -- TODO: Some builders are required only on certain platforms. For example, ===================================== hadrian/src/Rules/SourceDist.hs ===================================== @@ -23,12 +23,14 @@ sourceDistRules = do root -/- "source-dist" -/- "ghc-*-src.tar.xz" %> \fname -> do let tarName = takeFileName fname dropTarXz = dropExtension . dropExtension - treePath = root -/- "source-dist" -/- dropTarXz tarName + treeDir = dropTarXz tarName + treePath = root -/- "source-dist" -/- treeDir prepareTree treePath - runBuilder + runBuilderWithCmdOptions + [Cwd $ root -/- "source-dist"] (Tar Create) - ["cJf", fname, treePath] - ["cJf", fname] [treePath] + ["cJf", tarName, treeDir] + ["cJf", tarName] [treeDir] "GIT_COMMIT_ID" %> \fname -> writeFileChanged fname =<< setting ProjectGitCommitId "VERSION" %> \fname -> View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b69cc8842aa7e2df52b92a9c9ad3b9d8dcf624ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b69cc8842aa7e2df52b92a9c9ad3b9d8dcf624ab You're receiving 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 14 11:57:27 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 07:57:27 -0400 Subject: [Git][ghc/ghc][master] doc (Foldable): Add examples to Data.Foldable Message-ID: <5e95a5273adf9_61677c82e0c491966b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 1 changed file: - libraries/base/Data/Foldable.hs Changes: ===================================== libraries/base/Data/Foldable.hs ===================================== @@ -120,11 +120,44 @@ class Foldable t where {-# MINIMAL foldMap | foldr #-} -- | Combine the elements of a structure using a monoid. + -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> fold [[1, 2, 3], [4, 5], [6], []] + -- [1,2,3,4,5,6] + -- + -- >>> fold [Sum 1, Sum 3, Sum 5] + -- Sum {getSum = 9} + -- + -- Infinite structures never terminate: + -- + -- >>> fold (repeat Nothing) + -- * Hangs forever * fold :: Monoid m => t m -> m fold = foldMap id -- | Map each element of the structure to a monoid, -- and combine the results. + -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> foldMap Sum [1, 3, 5] + -- Sum {getSum = 9} + -- + -- >>> foldMap Product [1, 3, 5] + -- Product {getProduct = 15} + -- + -- >>> foldMap (replicate 3) [1, 2, 3] + -- [1,1,1,2,2,2,3,3,3] + -- + -- Infinite structures never terminate: + -- + -- >>> foldMap Sum [1..] + -- * Hangs forever * foldMap :: Monoid m => (a -> m) -> t a -> m {-# INLINE foldMap #-} -- This INLINE allows more list functions to fuse. See #9848. @@ -153,6 +186,49 @@ class Foldable t where -- -- @foldr f z = 'List.foldr' f z . 'toList'@ -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> foldr (||) False [False, True, False] + -- True + -- + -- >>> foldr (||) False [] + -- False + -- + -- >>> foldr (\nextChar reversedString -> reversedString ++ [nextChar]) "foo" ['a', 'b', 'c', 'd'] + -- "foodcba" + -- + -- ===== Infinite structures + -- + -- ⚠️ Applying 'foldr' to infinite structures usually doesn't terminate. + -- + -- It may still terminate in one of the following conditions: + -- + -- * the folding function is short-circuiting + -- * the folding function is lazy on its second argument + -- + -- ====== Short-circuiting + -- + -- '(||)' short-circuits on 'True' values, so the following terminates because there is a 'True' value finitely far from the left side: + -- + -- >>> foldr (||) False (True : repeat False) + -- True + -- + -- But the following doesn't terminate: + -- + -- >>> foldr (||) False (repeat False ++ [True]) + -- * Hangs forever * + -- + -- ====== Laziness in the second argument + -- + -- Applying 'foldr' to infinite structures terminates when the folding function is lazy on its second argument: + -- + -- >>> foldr (\nextElement accumulator -> nextElement : fmap (+3) accumulator) [42] (repeat 1) + -- [1,4,7,10,13,16,19,22,25,28,31,34,37,40,43... + -- + -- >>> take 5 $ foldr (\nextElement accumulator -> nextElement : fmap (+3) accumulator) [42] (repeat 1) + -- [1,4,7,10,13] foldr :: (a -> b -> b) -> b -> t a -> b foldr f z t = appEndo (foldMap (Endo #. f) t) z @@ -189,6 +265,28 @@ class Foldable t where -- -- @foldl f z = 'List.foldl' f z . 'toList'@ -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> foldl (+) 42 (Node (Leaf 1) 3 (Node Empty 4 (Leaf 2))) + -- 52 + -- + -- >>> foldl (+) 42 Empty + -- 42 + -- + -- >>> foldl (\string nextElement -> nextElement : string) "abcd" (Node (Leaf 'd') 'e' (Node Empty 'f' (Leaf 'g'))) + -- "gfedabcd" + -- + -- Left-folding infinite structures never terminates: + -- + -- >>> let infiniteNode = Node Empty 1 infiniteNode in foldl (+) 42 infiniteNode + -- * Hangs forever * + -- + -- Evaluating the head of the result (when applicable) does not terminate, unlike 'foldr': + -- + -- >>> let infiniteNode = Node Empty 'd' infiniteNode in take 5 (foldl (\string nextElement -> nextElement : string) "abc" infiniteNode) + -- * Hangs forever * foldl :: (b -> a -> b) -> b -> t a -> b foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z -- There's no point mucking around with coercions here, @@ -217,7 +315,30 @@ class Foldable t where -- -- ⚠️ This function is non-total and will raise a runtime exception if the structure happens to be empty. -- - -- @'foldr1' f = 'List.foldr1' f . 'toList'@ + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> foldr1 (+) [1..4] + -- 10 + -- + -- >>> foldr1 (+) [] + -- Exception: Prelude.foldr1: empty list + -- + -- >>> foldr1 (+) Nothing + -- *** Exception: foldr1: empty structure + -- + -- >>> foldr1 (-) [1..4] + -- -2 + -- + -- >>> foldr1 (&&) [True, False, True, True] + -- False + -- + -- >>> foldr1 (||) [False, False, True, True] + -- True + -- + -- >>> foldr1 (+) [1..] + -- * Hangs forever * foldr1 :: (a -> a -> a) -> t a -> a foldr1 f xs = fromMaybe (errorWithoutStackTrace "foldr1: empty structure") (foldr mf Nothing xs) @@ -232,6 +353,31 @@ class Foldable t where -- ⚠️ This function is non-total and will raise a runtime exception if the structure happens to be empty. -- -- @'foldl1' f = 'List.foldl1' f . 'toList'@ + -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> foldl1 (+) [1..4] + -- 10 + -- + -- >>> foldl1 (+) [] + -- *** Exception: Prelude.foldl1: empty list + -- + -- >>> foldl1 (+) Nothing + -- *** Exception: foldl1: empty structure + -- + -- >>> foldl1 (-) [1..4] + -- -8 + -- + -- >>> foldl1 (&&) [True, False, True, True] + -- False + -- + -- >>> foldl1 (||) [False, False, True, True] + -- True + -- + -- >>> foldl1 (+) [1..] + -- * Hangs forever * foldl1 :: (a -> a -> a) -> t a -> a foldl1 f xs = fromMaybe (errorWithoutStackTrace "foldl1: empty structure") (foldl mf Nothing xs) @@ -242,6 +388,27 @@ class Foldable t where -- | List of elements of a structure, from left to right. -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> toList Nothing + -- [] + -- + -- >>> toList (Just 42) + -- [42] + -- + -- >>> toList (Left "foo") + -- [] + -- + -- >>> toList (Node (Leaf 5) 17 (Node Empty 12 (Leaf 8))) + -- [5,17,12,8] + -- + -- For lists, 'toList' is the identity: + -- + -- >>> toList [1, 2, 3] + -- [1,2,3] + -- -- @since 4.8.0.0 toList :: t a -> [a] {-# INLINE toList #-} @@ -251,6 +418,21 @@ class Foldable t where -- optimized for structures that are similar to cons-lists, because there -- is no general way to do better. -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> null [] + -- True + -- + -- >>> null [1] + -- False + -- + -- 'null' terminates even for infinite structures: + -- + -- >>> null [1..] + -- False + -- -- @since 4.8.0.0 null :: t a -> Bool null = foldr (\_ _ -> False) True @@ -259,12 +441,48 @@ class Foldable t where -- default implementation is optimized for structures that are similar to -- cons-lists, because there is no general way to do better. -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> length [] + -- 0 + -- + -- >>> length ['a', 'b', 'c'] + -- 3 + -- >>> length [1..] + -- * Hangs forever * + -- -- @since 4.8.0.0 length :: t a -> Int length = foldl' (\c _ -> c+1) 0 -- | Does the element occur in the structure? -- + -- Note: 'elem' is often used in infix form. + -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> 3 `elem` [] + -- False + -- + -- >>> 3 `elem` [1,2] + -- False + -- + -- >>> 3 `elem` [1,2,3,4,5] + -- True + -- + -- For infinite structures, 'elem' terminates if the value exists at a + -- finite distance from the left side of the structure: + -- + -- >>> 3 `elem` [1..] + -- True + -- + -- >>> 3 `elem` ([4..] ++ [3]) + -- * Hangs forever * + -- -- @since 4.8.0.0 elem :: Eq a => a -> t a -> Bool elem = any . (==) @@ -273,12 +491,19 @@ class Foldable t where -- -- ⚠️ This function is non-total and will raise a runtime exception if the structure happens to be empty. -- - -- === __Examples__ + -- ==== __Examples__ + -- + -- Basic usage: + -- -- >>> maximum [1..10] -- 10 + -- -- >>> maximum [] -- *** Exception: Prelude.maximum: empty list -- + -- >>> maximum Nothing + -- *** Exception: maximum: empty structure + -- -- @since 4.8.0.0 maximum :: forall a . Ord a => t a -> a maximum = fromMaybe (errorWithoutStackTrace "maximum: empty structure") . @@ -288,12 +513,19 @@ class Foldable t where -- -- ⚠️ This function is non-total and will raise a runtime exception if the structure happens to be empty -- - -- === __Examples__ + -- ==== __Examples__ + -- + -- Basic usage: + -- -- >>> minimum [1..10] -- 1 + -- -- >>> minimum [] -- *** Exception: Prelude.minimum: empty list -- + -- >>> minimum Nothing + -- *** Exception: minimum: empty structure + -- -- @since 4.8.0.0 minimum :: forall a . Ord a => t a -> a minimum = fromMaybe (errorWithoutStackTrace "minimum: empty structure") . @@ -301,6 +533,25 @@ class Foldable t where -- | The 'sum' function computes the sum of the numbers of a structure. -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> sum [] + -- 0 + -- + -- >>> sum [42] + -- 42 + -- + -- >>> sum [1..10] + -- 55 + -- + -- >>> sum [4.1, 2.0, 1.7] + -- 7.8 + -- + -- >>> sum [1..] + -- * Hangs forever * + -- -- @since 4.8.0.0 sum :: Num a => t a -> a sum = getSum #. foldMap Sum @@ -308,6 +559,25 @@ class Foldable t where -- | The 'product' function computes the product of the numbers of a -- structure. -- + -- ==== __Examples__ + -- + -- Basic usage: + -- + -- >>> product [] + -- 1 + -- + -- >>> product [42] + -- 42 + -- + -- >>> product [1..10] + -- 3628800 + -- + -- >>> product [4.1, 2.0, 1.7] + -- 13.939999999999998 + -- + -- >>> product [1..] + -- * Hangs forever * + -- -- @since 4.8.0.0 product :: Num a => t a -> a product = getProduct #. foldMap Product @@ -557,6 +827,16 @@ deriving instance Foldable Down -- | Monadic fold over the elements of a structure, -- associating to the right, i.e. from right to left. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> foldrM (\string acc -> print string >> pure (acc + length string)) 42 ["Hello", "world", "!"] +-- "!" +-- "world" +-- "Hello" +-- 53 foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b foldrM f z0 xs = foldl c return xs z0 -- See Note [List fusion and continuations in 'c'] @@ -565,6 +845,16 @@ foldrM f z0 xs = foldl c return xs z0 -- | Monadic fold over the elements of a structure, -- associating to the left, i.e. from left to right. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> foldlM (\acc string -> print string >> pure (acc + length string)) 42 ["Hello", "world", "!"] +-- "Hello" +-- "world" +-- "!" +-- 53 foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b foldlM f z0 xs = foldr c return xs z0 -- See Note [List fusion and continuations in 'c'] @@ -574,6 +864,15 @@ foldlM f z0 xs = foldr c return xs z0 -- | Map each element of a structure to an action, evaluate these -- actions from left to right, and ignore the results. For a version -- that doesn't ignore the results see 'Data.Traversable.traverse'. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> traverse_ print ["Hello", "world", "!"] +-- "Hello" +-- "world" +-- "!" traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f () traverse_ f = foldr c (pure ()) -- See Note [List fusion and continuations in 'c'] @@ -583,6 +882,10 @@ traverse_ f = foldr c (pure ()) -- | 'for_' is 'traverse_' with its arguments flipped. For a version -- that doesn't ignore the results see 'Data.Traversable.for'. -- +-- ==== __Examples__ +-- +-- Basic usage: +-- -- >>> for_ [1..4] print -- 1 -- 2 @@ -616,6 +919,15 @@ forM_ = flip mapM_ -- | Evaluate each action in the structure from left to right, and -- ignore the results. For a version that doesn't ignore the results -- see 'Data.Traversable.sequenceA'. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> sequenceA_ [print "Hello", print "world", print "!"] +-- "Hello" +-- "world" +-- "!" sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f () sequenceA_ = foldr c (pure ()) -- See Note [List fusion and continuations in 'c'] @@ -636,6 +948,10 @@ sequence_ = foldr c (return ()) -- | The sum of a collection of actions, generalizing 'concat'. -- +-- ==== __Examples__ +-- +-- Basic usage: +-- -- >>> asum [Just "Hello", Nothing, Just "World"] -- Just "Hello" asum :: (Foldable t, Alternative f) => t (f a) -> f a @@ -649,12 +965,32 @@ msum :: (Foldable t, MonadPlus m) => t (m a) -> m a msum = asum -- | The concatenation of all the elements of a container of lists. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> concat (Just [1, 2, 3]) +-- [1,2,3] +-- +-- >>> concat (Node (Leaf [1, 2, 3]) [4, 5] (Node Empty [6] (Leaf []))) +-- [1,2,3,4,5,6] concat :: Foldable t => t [a] -> [a] concat xs = build (\c n -> foldr (\x y -> foldr c y x) n xs) {-# INLINE concat #-} -- | Map a function over all the elements of a container and concatenate -- the resulting lists. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> concatMap (take 3) [[1..], [10..], [100..], [1000..]] +-- [1,2,3,10,11,12,100,101,102,1000,1001,1002] +-- +-- >>> concatMap (take 3) (Node (Leaf [1..]) [10..] Empty) +-- [1,2,3,10,11,12] concatMap :: Foldable t => (a -> [b]) -> t a -> [b] concatMap f xs = build (\c n -> foldr (\x b -> foldr c b (f x)) n xs) {-# INLINE concatMap #-} @@ -664,25 +1000,114 @@ concatMap f xs = build (\c n -> foldr (\x b -> foldr c b (f x)) n xs) -- | 'and' returns the conjunction of a container of Bools. For the -- result to be 'True', the container must be finite; 'False', however, -- results from a 'False' value finitely far from the left end. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> and [] +-- True +-- +-- >>> and [True] +-- True +-- +-- >>> and [False] +-- False +-- +-- >>> and [True, True, False] +-- False +-- +-- >>> and (False : repeat True) -- Infinite list [False,True,True,True,True,True,True... +-- False +-- +-- >>> and (repeat True) +-- * Hangs forever * and :: Foldable t => t Bool -> Bool and = getAll #. foldMap All -- | 'or' returns the disjunction of a container of Bools. For the -- result to be 'False', the container must be finite; 'True', however, -- results from a 'True' value finitely far from the left end. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> or [] +-- False +-- +-- >>> or [True] +-- True +-- +-- >>> or [False] +-- False +-- +-- >>> or [True, True, False] +-- True +-- +-- >>> or (True : repeat False) -- Infinite list [True,False,False,False,False,False,False... +-- True +-- +-- >>> or (repeat False) +-- * Hangs forever * or :: Foldable t => t Bool -> Bool or = getAny #. foldMap Any -- | Determines whether any element of the structure satisfies the predicate. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> any (> 3) [] +-- False +-- +-- >>> any (> 3) [1,2] +-- False +-- +-- >>> any (> 3) [1,2,3,4,5] +-- True +-- +-- >>> any (> 3) [1..] +-- True +-- +-- >>> any (> 3) [0, -1..] +-- * Hangs forever * any :: Foldable t => (a -> Bool) -> t a -> Bool any p = getAny #. foldMap (Any #. p) -- | Determines whether all elements of the structure satisfy the predicate. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> all (> 3) [] +-- True +-- +-- >>> all (> 3) [1,2] +-- False +-- +-- >>> all (> 3) [1,2,3,4,5] +-- False +-- +-- >>> all (> 3) [1..] +-- False +-- +-- >>> all (> 3) [4..] +-- * Hangs forever * all :: Foldable t => (a -> Bool) -> t a -> Bool all p = getAll #. foldMap (All #. p) -- | The largest element of a non-empty structure with respect to the -- given comparison function. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> maximumBy (compare `on` length) ["Hello", "World", "!", "Longest", "bar"] +-- "Longest" -- See Note [maximumBy/minimumBy space usage] maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a @@ -693,6 +1118,13 @@ maximumBy cmp = foldl1 max' -- | The least element of a non-empty structure with respect to the -- given comparison function. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> minimumBy (compare `on` length) ["Hello", "World", "!", "Longest", "bar"] +-- "!" -- See Note [maximumBy/minimumBy space usage] minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a @@ -702,12 +1134,47 @@ minimumBy cmp = foldl1 min' _ -> x -- | 'notElem' is the negation of 'elem'. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> 3 `notElem` [] +-- True +-- +-- >>> 3 `notElem` [1,2] +-- True +-- +-- >>> 3 `notElem` [1,2,3,4,5] +-- False +-- +-- For infinite structures, 'notElem' terminates if the value exists at a +-- finite distance from the left side of the structure: +-- +-- >>> 3 `notElem` [1..] +-- False +-- +-- >>> 3 `notElem` ([4..] ++ [3]) +-- * Hangs forever * notElem :: (Foldable t, Eq a) => a -> t a -> Bool notElem x = not . elem x -- | The 'find' function takes a predicate and a structure and returns -- the leftmost element of the structure matching the predicate, or -- 'Nothing' if there is no such element. +-- +-- ==== __Examples__ +-- +-- Basic usage: +-- +-- >>> find (> 42) [0, 5..] +-- Just 45 +-- +-- >>> find (> 4) (Node (Leaf 3) 17 (Node Empty 12 (Leaf 8))) +-- Just 17 +-- +-- >>> find (> 12) [1..7] +-- Nothing find :: Foldable t => (a -> Bool) -> t a -> Maybe a find p = getFirst . foldMap (\ x -> First (if p x then Just x else Nothing)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d0c3b0696f1ca809ebd83b5fc2c0b911cde38e77 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d0c3b0696f1ca809ebd83b5fc2c0b911cde38e77 You're receiving 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 14 12:05:54 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 14 Apr 2020 08:05:54 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18049 Message-ID: <5e95a722b936f_616713503ee0492147f@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/T18049 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18049 You're receiving 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 14 15:07:19 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 14 Apr 2020 11:07:19 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/elem_rule_rework Message-ID: <5e95d1a7751f9_616765c7a284972031@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/elem_rule_rework at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/elem_rule_rework You're receiving 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 14 16:38:50 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Tue, 14 Apr 2020 12:38:50 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 78 commits: Remove unused `ghciTablesNextToCode` from compiler proper Message-ID: <5e95e71a33b6b_616713503ee049922a3@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - d1a0b297 by John Ericson at 2020-04-14T12:36:21-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. - - - - - 30 changed files: - .gitlab-ci.yml - CODEOWNERS - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/Switch/Implement.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2e3d0807c6045c41a4cd82128df01378c512d58...d1a0b2977685827360a64f2001d61d5c8501cde6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2e3d0807c6045c41a4cd82128df01378c512d58...d1a0b2977685827360a64f2001d61d5c8501cde6 You're receiving 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 14 16:49:44 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Tue, 14 Apr 2020 12:49:44 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e95e9a84c30a_616713503ee0499612d@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: b02ebd2e by John Ericson at 2020-04-14T12:46:38-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -23,8 +23,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +62,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +73,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +173,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +244,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +277,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +304,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +326,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +526,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +562,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +577,35 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +644,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +729,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +745,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +762,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +783,12 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +830,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +856,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +868,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +897,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b02ebd2e3ff97ffd6130a1d6829fa369f353e2c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b02ebd2e3ff97ffd6130a1d6829fa369f353e2c9 You're receiving 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 14 17:46:32 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Tue, 14 Apr 2020 13:46:32 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e95f6f86b8ca_61673f8198ee100c5005593@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: fdbca7d8 by John Ericson at 2020-04-14T13:43:57-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -23,8 +23,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +62,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +73,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +173,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +244,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +277,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +304,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +326,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +526,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +562,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +577,33 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +642,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +727,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +743,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +760,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +781,10 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +826,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +852,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +864,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +893,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdbca7d832c0c9fab9008f170cb131cb30e218aa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdbca7d832c0c9fab9008f170cb131cb30e218aa You're receiving 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 14 19:58:18 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 15:58:18 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 16 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5e9615dae10ee_616776d1c74502702e@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 8cc5cdf7 by Ben Gamari at 2020-04-14T15:57:57-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - a4871980 by Ben Gamari at 2020-04-14T15:57:58-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 33a8db95 by Ben Gamari at 2020-04-14T15:57:59-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - ac65ee8c by Matthew Pickering at 2020-04-14T15:57:59-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - aa0c1c72 by Daniel Gröber at 2020-04-14T15:58:08-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 9f00bd86 by Daniel Gröber at 2020-04-14T15:58:08-04:00 rts: Expand and add more notes regarding slop - - - - - bf069c94 by Daniel Gröber at 2020-04-14T15:58:09-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - 795ddb33 by Daniel Gröber at 2020-04-14T15:58:09-04:00 rts: Underline some Notes as is conventional - - - - - 3090e915 by Daniel Gröber at 2020-04-14T15:58:10-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - b0e2ff82 by Daniel Gröber at 2020-04-14T15:58:10-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 4c46841f by Daniel Gröber at 2020-04-14T15:58:10-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - b48d78d3 by Ryan Scott at 2020-04-14T15:58:10-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 30 changed files: - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/ghc.cabal.in - ghc.mk - hadrian/src/Builder.hs - hadrian/src/Rules/SourceDist.hs - hadrian/src/Settings/Builders/Ghc.hs - includes/rts/storage/ClosureMacros.h - includes/rts/storage/GC.h - libraries/base/Data/Foldable.hs - libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc - libraries/exceptions - libraries/ghci/ghci.cabal.in - libraries/template-haskell/template-haskell.cabal.in - libraries/text - rts/Apply.cmm - rts/LdvProfile.c - rts/PrimOps.cmm - rts/ProfHeap.c - rts/StgCRun.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/16928cb1f2933f082aa17a3d9042216b8a5e5726...b48d78d3fa1c4e0b70e9f98478a101fb4dd57ea3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/16928cb1f2933f082aa17a3d9042216b8a5e5726...b48d78d3fa1c4e0b70e9f98478a101fb4dd57ea3 You're receiving 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 14 23:30:52 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 14 Apr 2020 19:30:52 -0400 Subject: [Git][ghc/ghc][wip/T17173] 25 commits: Make NoExtCon fields strict Message-ID: <5e9647ac3bf51_61677c82e0c50477a4@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 9d874e1e by Simon Peyton Jones at 2020-04-14T23:15:00+01:00 Do eager instantation in terms This is a first draft of a patch for #17173. It will need a proper commit message before we are done! - - - - - bbd88ffb by Simon Peyton Jones at 2020-04-14T23:16:19+01:00 Major refactor of typechecking applications Following conversation with Richard today, I have done major surgery on tcApp and friends. Fewer arguments, less plumbing, all good. I also completely killed off ir_inst. It's not as well documented as I want, yet, but I'm pushing it up for Richard's review. (This message will be replaced with a proper commit message.) - - - - - a785c222 by Simon Peyton Jones at 2020-04-15T00:30:30+01:00 Wibbles, esp to error reporting - - - - - 29 changed files: - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f39a0d86de843c105dc9cd4e0bd631176300d7f7...a785c222ff5900b02cf23de0d864bd5a7de9f164 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f39a0d86de843c105dc9cd4e0bd631176300d7f7...a785c222ff5900b02cf23de0d864bd5a7de9f164 You're receiving 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 15 03:28:28 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:28:28 -0400 Subject: [Git][ghc/ghc][master] StgCRun: Enable unwinding only on Linux Message-ID: <5e967f5cd6dfe_616776d1c74505748b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 1 changed file: - rts/StgCRun.c Changes: ===================================== rts/StgCRun.c ===================================== @@ -29,6 +29,13 @@ #include "PosixSource.h" #include "ghcconfig.h" +// Enable DWARF Call-Frame Information (used for stack unwinding) on Linux. +// This is not supported on Darwin and SmartOS due to assembler differences +// (#15207). +#if defined(linux_HOST_OS) +#define ENABLE_UNWINDING +#endif + #if defined(sparc_HOST_ARCH) || defined(USE_MINIINTERPRETER) /* include Stg.h first because we want real machine regs in here: we * have to get the value of R1 back from Stg land to C land intact. @@ -405,7 +412,7 @@ StgRunIsImplementedInAssembler(void) "movq %%xmm15,136(%%rax)\n\t" #endif -#if !defined(darwin_HOST_OS) +#if defined(ENABLE_UNWINDING) /* * Let the unwinder know where we saved the registers * See Note [Unwinding foreign exports on x86-64]. @@ -444,7 +451,7 @@ StgRunIsImplementedInAssembler(void) #error "RSP_DELTA too big" #endif "\n\t" -#endif /* !defined(darwin_HOST_OS) */ +#endif /* defined(ENABLE_UNWINDING) */ /* * Set BaseReg @@ -519,7 +526,7 @@ StgRunIsImplementedInAssembler(void) "i"(RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE /* rip relative to cfa */) -#if !defined(darwin_HOST_OS) +#if defined(ENABLE_UNWINDING) , "i"((RSP_DELTA & 127) | (128 * ((RSP_DELTA >> 7) > 0))) /* signed LEB128-encoded delta from rsp - byte 1 */ #if (RSP_DELTA >> 7) > 0 @@ -538,7 +545,7 @@ StgRunIsImplementedInAssembler(void) #endif #undef RSP_DELTA -#endif /* !defined(darwin_HOST_OS) */ +#endif /* defined(ENABLE_UNWINDING) */ ); /* View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5b08e0c06e038448a63aa9bd7f163b23d824ba4b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5b08e0c06e038448a63aa9bd7f163b23d824ba4b You're receiving 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 15 03:29:13 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:29:13 -0400 Subject: [Git][ghc/ghc][master] rts: Don't mark evacuate_large as inline Message-ID: <5e967f89be29c_61673f8199536d945060265@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 1 changed file: - rts/sm/Evac.c Changes: ===================================== rts/sm/Evac.c ===================================== @@ -298,7 +298,7 @@ copy(StgClosure **p, const StgInfoTable *info, that has been evacuated, or unset otherwise. -------------------------------------------------------------------------- */ -STATIC_INLINE void +static void evacuate_large(StgPtr p) { bdescr *bd; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27cc2e7b1c1268e59c9d16b4530f27c0d40e9464 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27cc2e7b1c1268e59c9d16b4530f27c0d40e9464 You're receiving 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 15 03:29:59 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:29:59 -0400 Subject: [Git][ghc/ghc][master] base: Enable large file support for OFD locking impl. Message-ID: <5e967fb732a60_616776d1c7450632c3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 1 changed file: - libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc Changes: ===================================== libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc ===================================== @@ -12,6 +12,9 @@ module GHC.IO.Handle.Lock.LinuxOFD where import GHC.Base () -- Make implicit dependency known to build system #else +-- Not only is this a good idea but it also works around #17950. +#define _FILE_OFFSET_BITS 64 + #include #include View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9853fc5e3556e733b56976b0a2fce9e82130a9ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9853fc5e3556e733b56976b0a2fce9e82130a9ef You're receiving 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 15 03:30:35 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:30:35 -0400 Subject: [Git][ghc/ghc][master] Hadrian: Make -i paths absolute Message-ID: <5e967fdb2f493_616713503ee050661e3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 1 changed file: - hadrian/src/Settings/Builders/Ghc.hs Changes: ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -11,6 +11,7 @@ import Settings.Builders.Common import Settings.Warnings import qualified Context as Context import Rules.Libffi (libffiName) +import System.Directory ghcBuilderArgs :: Args ghcBuilderArgs = mconcat [ compileAndLinkHs, compileC, findHsDependencies @@ -215,18 +216,20 @@ packageGhcArgs = do includeGhcArgs :: Args includeGhcArgs = do pkg <- getPackage - path <- getBuildPath + path <- exprIO . makeAbsolute =<< getBuildPath context <- getContext srcDirs <- getContextData srcDirs - autogen <- expr $ autogenPath context + abSrcDirs <- exprIO $ mapM makeAbsolute [ (pkgPath pkg -/- dir) | dir <- srcDirs ] + autogen <- expr (autogenPath context) + cautogen <- exprIO (makeAbsolute autogen) stage <- getStage - libPath <- expr $ stageLibPath stage + libPath <- expr (stageLibPath stage) let cabalMacros = autogen -/- "cabal_macros.h" expr $ need [cabalMacros] mconcat [ arg "-i" , arg $ "-i" ++ path - , arg $ "-i" ++ autogen - , pure [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ] + , arg $ "-i" ++ cautogen + , pure [ "-i" ++ d | d <- abSrcDirs ] , cIncludeArgs , arg $ "-I" ++ libPath , arg $ "-optc-I" ++ libPath View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b41f21bbfa9e266ba6654b08c3f9fec549c8bca -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b41f21bbfa9e266ba6654b08c3f9fec549c8bca You're receiving 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 15 03:31:13 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:31:13 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Zero out pinned block alignment slop when profiling Message-ID: <5e968001dc32c_61673f8199536d945068952@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - 7 changed files: - includes/rts/storage/ClosureMacros.h - includes/rts/storage/GC.h - rts/Apply.cmm - rts/PrimOps.cmm - rts/ProfHeap.c - rts/sm/Sanity.c - rts/sm/Storage.c Changes: ===================================== includes/rts/storage/ClosureMacros.h ===================================== @@ -474,31 +474,39 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) OVERWRITING_CLOSURE(p) on the old closure that is about to be overwritten. - Note [zeroing slop] + Note [zeroing slop when overwriting closures] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - In some scenarios we write zero words into "slop"; memory that is - left unoccupied after we overwrite a closure in the heap with a - smaller closure. + When we overwrite a closure in the heap with a smaller one, in some scenarios + we need to write zero words into "slop"; the memory that is left + unoccupied. See Note [slop on the heap] Zeroing slop is required for: - - full-heap sanity checks (DEBUG, and +RTS -DS) - - LDV profiling (PROFILING, and +RTS -hb) + - full-heap sanity checks (DEBUG, and +RTS -DS), - Zeroing slop must be disabled for: + - LDV profiling (PROFILING, and +RTS -hb) and - - THREADED_RTS with +RTS -N2 and greater, because we cannot - overwrite slop when another thread might be reading it. + However we can get into trouble if we're zeroing slop for ordinarily + immutable closures when using multiple threads, since there is nothing + preventing another thread from still being in the process of reading the + memory we're about to zero. - Hence, slop is zeroed when either: + Thus, with the THREADED RTS and +RTS -N2 or greater we must not zero + immutable closure's slop. - - PROFILING && era <= 0 (LDV is on) - - !THREADED_RTS && DEBUG + Hence, an immutable closure's slop is zeroed when either: - And additionally: + - PROFILING && era > 0 (LDV is on) or + - !THREADED && DEBUG - - LDV profiling and +RTS -N2 are incompatible - - full-heap sanity checks are disabled for THREADED_RTS + Additionally: + + - LDV profiling and +RTS -N2 are incompatible, + + - full-heap sanity checks are disabled for the THREADED RTS, at least when + they don't run right after GC when there is no slop. + See Note [heap sanity checking with SMP]. -------------------------------------------------------------------------- */ @@ -534,7 +542,7 @@ EXTERN_INLINE void overwritingClosure_ (StgClosure *p, EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size, bool prim USED_IF_PROFILING) { #if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK - // see Note [zeroing slop], also #8402 + // see Note [zeroing slop when overwriting closures], also #8402 if (era <= 0) return; #endif ===================================== includes/rts/storage/GC.h ===================================== @@ -170,10 +170,13 @@ extern generation * oldest_gen; Allocates memory from the nursery in the current Capability. - StgPtr allocatePinned(Capability *cap, W_ n) + StgPtr allocatePinned(Capability *cap, W_ n, W_ alignment, W_ align_off) Allocates a chunk of contiguous store n words long, which is at a fixed - address (won't be moved by GC). + address (won't be moved by GC). The + word at the byte offset 'align_off' + will be aligned to 'alignment', which + must be a power of two. Returns a pointer to the first word. Always succeeds. @@ -191,7 +194,7 @@ extern generation * oldest_gen; StgPtr allocate ( Capability *cap, W_ n ); StgPtr allocateMightFail ( Capability *cap, W_ n ); -StgPtr allocatePinned ( Capability *cap, W_ n ); +StgPtr allocatePinned ( Capability *cap, W_ n, W_ alignment, W_ align_off); /* memory allocator for executable memory */ typedef void* AdjustorWritable; ===================================== rts/Apply.cmm ===================================== @@ -689,7 +689,7 @@ for: // Because of eager blackholing the closure no longer has correct size so // threadPaused() can't correctly zero the slop, so we do it here. See #15571 - // and Note [zeroing slop]. + // and Note [zeroing slop when overwriting closures]. OVERWRITING_CLOSURE_SIZE(ap, BYTES_TO_WDS(SIZEOF_StgThunkHeader) + 2 + Words); ENTER_R1(); ===================================== rts/PrimOps.cmm ===================================== @@ -89,22 +89,15 @@ stg_newPinnedByteArrayzh ( W_ n ) /* When we actually allocate memory, we need to allow space for the header: */ bytes = bytes + SIZEOF_StgArrBytes; - /* And we want to align to BA_ALIGN bytes, so we need to allow space - to shift up to BA_ALIGN - 1 bytes: */ - bytes = bytes + BA_ALIGN - 1; /* Now we convert to a number of words: */ words = ROUNDUP_BYTES_TO_WDS(bytes); - ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words); + ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words, BA_ALIGN, SIZEOF_StgArrBytes); if (p == NULL) { jump stg_raisezh(base_GHCziIOziException_heapOverflow_closure); } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - /* Now we need to move p forward so that the payload is aligned - to BA_ALIGN bytes: */ - p = p + ((-p - SIZEOF_StgArrBytes) & BA_MASK); - /* No write barrier needed since this is a new allocation. */ SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; @@ -121,7 +114,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment ) /* we always supply at least word-aligned memory, so there's no need to allow extra space for alignment if the requirement is less than a word. This also prevents mischief with alignment == 0. */ - if (alignment <= SIZEOF_W) { alignment = 1; } + if (alignment <= SIZEOF_W) { alignment = SIZEOF_W; } bytes = n; @@ -131,23 +124,15 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment ) /* When we actually allocate memory, we need to allow space for the header: */ bytes = bytes + SIZEOF_StgArrBytes; - /* And we want to align to bytes, so we need to allow space - to shift up to bytes: */ - bytes = bytes + alignment - 1; /* Now we convert to a number of words: */ words = ROUNDUP_BYTES_TO_WDS(bytes); - ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words); + ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words, alignment, SIZEOF_StgArrBytes); if (p == NULL) { jump stg_raisezh(base_GHCziIOziException_heapOverflow_closure); } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - /* Now we need to move p forward so that the payload is aligned - to bytes. Note that we are assuming that - is a power of 2, which is technically not guaranteed */ - p = p + ((-p - SIZEOF_StgArrBytes) & (alignment - 1)); - /* No write barrier needed since this is a new allocation. */ SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; ===================================== rts/ProfHeap.c ===================================== @@ -1275,8 +1275,22 @@ heapCensusChain( Census *census, bdescr *bd ) heapProfObject(census,(StgClosure*)p,size,prim); p += size; - /* skip over slop */ - while (p < bd->free && !*p) p++; // skip slop + + /* skip over slop, see Note [slop on the heap] */ + while (p < bd->free && !*p) p++; + /* Note [skipping slop in the heap profiler] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * We make sure to zero slop that can remain after a major GC so + * here we can assume any slop words we see until the block's free + * pointer are zero. Since info pointers are always nonzero we can + * use this to scan for the next valid heap closure. + * + * Note that not all types of slop are relevant here, only the ones + * that can reman after major GC. So essentially just large objects + * and pinned objects. All other closures will have been packed nice + * and thight into fresh blocks. + */ } } } ===================================== rts/sm/Sanity.c ===================================== @@ -475,7 +475,7 @@ void checkHeapChain (bdescr *bd) ASSERT( size >= MIN_PAYLOAD_SIZE + sizeofW(StgHeader) ); p += size; - /* skip over slop */ + /* skip over slop, see Note [slop on the heap] */ while (p < bd->free && (*p < 0x1000 || !LOOKS_LIKE_INFO_PTR(*p))) { p++; } } @@ -796,12 +796,17 @@ static void checkGeneration (generation *gen, ASSERT(countBlocks(gen->large_objects) == gen->n_large_blocks); #if defined(THREADED_RTS) + // Note [heap sanity checking with SMP] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // heap sanity checking doesn't work with SMP for two reasons: - // * we can't zero the slop (see Updates.h). However, we can sanity-check - // the heap after a major gc, because there is no slop. // - // * the nonmoving collector may be mutating its large object lists, unless we - // were in fact called by the nonmoving collector. + // * We can't zero the slop. However, we can sanity-check the heap after a + // major gc, because there is no slop. See also Updates.h and Note + // [zeroing slop when overwriting closures]. + // + // * The nonmoving collector may be mutating its large object lists, + // unless we were in fact called by the nonmoving collector. if (!after_major_gc) return; #endif ===================================== rts/sm/Storage.c ===================================== @@ -907,6 +907,54 @@ accountAllocation(Capability *cap, W_ n) } +/* Note [slop on the heap] + * ~~~~~~~~~~~~~~~~~~~~~~~ + * + * We use the term "slop" to refer to allocated memory on the heap which isn't + * occupied by any closure. Usually closures are packet tightly into the heap + * blocks, storage for one immediately following another. However there are + * situations where slop is left behind: + * + * - Allocating large objects (BF_LARGE) + * + * These are given an entire block, but if they don't fill the entire block + * the rest is slop. See allocateMightFail in Storage.c. + * + * - Allocating pinned objects with alignment (BF_PINNED) + * + * These are packet into blocks like normal closures, however they + * can have alignment constraints and any memory that needed to be skipped for + * alignment becomes slop. See allocatePinned in Storage.c. + * + * - Shrinking (Small)Mutable(Byte)Array# + * + * The size of these closures can be decreased after allocation, leaving any, + * now unused memory, behind as slop. See stg_resizzeMutableByteArrayzh, + * stg_shrinkSmallMutableArrayzh, and stg_shrinkMutableByteArrayzh in + * PrimOps.cmm. + * + * This type of slop is extra tricky because it can also be pinned and + * large. + * + * - Overwriting closures + * + * During GC the RTS overwrites closures with forwarding pointers, this can + * leave slop behind depending on the size of the closure being + * overwritten. See Note [zeroing slop when overwriting closures]. + * + * Under various ways we actually zero slop so we can linearly scan over blocks + * of closures. This trick is used by the sanity checking code and the heap + * profiler, see Note [skipping slop in the heap profiler]. + * + * When profiling we zero: + * - Pinned object alignment slop, see MEMSET_IF_PROFILING_W in allocatePinned. + * - Shrunk array slop, see OVERWRITING_MUTABLE_CLOSURE. + * + * When performing LDV profiling or using a (single threaded) debug RTS we zero + * slop even when overwriting immutable closures, see Note [zeroing slop when + * overwriting closures]. + */ + /* ----------------------------------------------------------------------------- StgPtr allocate (Capability *cap, W_ n) @@ -1059,6 +1107,26 @@ allocateMightFail (Capability *cap, W_ n) return p; } +/** + * Calculate the number of words we need to add to 'p' so it satisfies the + * alignment constraint '(p + off) & (align-1) == 0'. + */ +#define ALIGN_WITH_OFF_W(p, align, off) \ + (((-((uintptr_t)p) - off) & (align-1)) / sizeof(W_)) + +/** + * When profiling we zero the space used for alignment. This allows us to + * traverse pinned blocks in the heap profiler. + * + * See Note [skipping slop in the heap profiler] + */ +#if defined(PROFILING) +#define MEMSET_IF_PROFILING_W(p, val, len_w) memset(p, val, (len_w) * sizeof(W_)) +#else +#define MEMSET_IF_PROFILING_W(p, val, len_w) \ + do { (void)(p); (void)(val); (void)(len_w); } while(0) +#endif + /* --------------------------------------------------------------------------- Allocate a fixed/pinned object. @@ -1084,29 +1152,49 @@ allocateMightFail (Capability *cap, W_ n) ------------------------------------------------------------------------- */ StgPtr -allocatePinned (Capability *cap, W_ n) +allocatePinned (Capability *cap, W_ n /*words*/, W_ alignment /*bytes*/, W_ align_off /*bytes*/) { StgPtr p; bdescr *bd; + // Alignment and offset have to be a power of two + ASSERT(alignment && !(alignment & (alignment - 1))); + ASSERT(alignment >= sizeof(W_)); + + ASSERT(!(align_off & (align_off - 1))); + + const StgWord alignment_w = alignment / sizeof(W_); + // If the request is for a large object, then allocate() // will give us a pinned object anyway. if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) { - p = allocateMightFail(cap, n); + // For large objects we don't bother optimizing the number of words + // allocated for alignment reasons. Here we just allocate the maximum + // number of extra words we could possibly need to satisfy the alignment + // constraint. + p = allocateMightFail(cap, n + alignment_w - 1); if (p == NULL) { return NULL; } else { Bdescr(p)->flags |= BF_PINNED; + W_ off_w = ALIGN_WITH_OFF_W(p, alignment, align_off); + MEMSET_IF_PROFILING_W(p, 0, off_w); + p += off_w; + MEMSET_IF_PROFILING_W(p + n, 0, alignment_w - off_w - 1); return p; } } - accountAllocation(cap, n); bd = cap->pinned_object_block; + W_ off_w = 0; + + if(bd) + off_w = ALIGN_WITH_OFF_W(bd->free, alignment, align_off); + // If we don't have a block of pinned objects yet, or the current // one isn't large enough to hold the new object, get a new one. - if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) { + if (bd == NULL || (bd->free + off_w + n) > (bd->start + BLOCK_SIZE_W)) { // stash the old block on cap->pinned_object_blocks. On the // next GC cycle these objects will be moved to @@ -1158,10 +1246,20 @@ allocatePinned (Capability *cap, W_ n) // the next GC the BF_EVACUATED flag will be cleared, and the // block will be promoted as usual (if anything in it is // live). + + off_w = ALIGN_WITH_OFF_W(bd->free, alignment, align_off); } p = bd->free; + + MEMSET_IF_PROFILING_W(p, 0, off_w); + + n += off_w; + p += off_w; bd->free += n; + + accountAllocation(cap, n); + return p; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b41f21bbfa9e266ba6654b08c3f9fec549c8bca...c3c0f662df06500a11970fd391d0a88e081a5296 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b41f21bbfa9e266ba6654b08c3f9fec549c8bca...c3c0f662df06500a11970fd391d0a88e081a5296 You're receiving 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 15 03:32:23 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:32:23 -0400 Subject: [Git][ghc/ghc][master] Bump template-haskell version to 2.17.0.0 Message-ID: <5e968047b99bf_616776d1c7450769a9@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 7 changed files: - compiler/ghc.cabal.in - ghc.mk - libraries/exceptions - libraries/ghci/ghci.cabal.in - libraries/template-haskell/template-haskell.cabal.in - libraries/text - utils/ghc-cabal/ghc.mk Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -69,7 +69,7 @@ Library containers >= 0.5 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, - template-haskell == 2.16.*, + template-haskell == 2.17.*, hpc == 0.6.*, transformers == 0.5.*, ghc-boot == @ProjectVersionMunged@, ===================================== ghc.mk ===================================== @@ -413,8 +413,8 @@ else # CLEANING # Packages that are built by stage0. These packages are dependencies of # programs such as GHC and ghc-pkg, that we do not assume the stage0 # compiler already has installed (or up-to-date enough). - -PACKAGES_STAGE0 = binary text transformers mtl parsec Cabal/Cabal hpc ghc-boot-th ghc-boot template-haskell ghc-heap ghci +# Note that these must be given in topological order. +PACKAGES_STAGE0 = binary transformers mtl hpc ghc-boot-th ghc-boot template-haskell text parsec Cabal/Cabal ghc-heap ghci ifeq "$(Windows_Host)" "NO" PACKAGES_STAGE0 += terminfo endif @@ -441,14 +441,14 @@ PACKAGES_STAGE1 += process PACKAGES_STAGE1 += hpc PACKAGES_STAGE1 += pretty PACKAGES_STAGE1 += binary -PACKAGES_STAGE1 += text PACKAGES_STAGE1 += transformers PACKAGES_STAGE1 += mtl -PACKAGES_STAGE1 += parsec -PACKAGES_STAGE1 += Cabal/Cabal PACKAGES_STAGE1 += ghc-boot-th PACKAGES_STAGE1 += ghc-boot PACKAGES_STAGE1 += template-haskell +PACKAGES_STAGE1 += text +PACKAGES_STAGE1 += parsec +PACKAGES_STAGE1 += Cabal/Cabal PACKAGES_STAGE1 += ghc-compact PACKAGES_STAGE1 += ghc-heap ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit 0a1f9ff0f407da360fc9405a07d5d06d28e6c077 +Subproject commit fe4166f8d23d8288ef2cbbf9e36118b6b99e0d7d ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -81,7 +81,7 @@ library ghc-boot == @ProjectVersionMunged@, ghc-boot-th == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.16.*, + template-haskell == 2.17.*, transformers == 0.5.* if !os(windows) ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -3,7 +3,7 @@ -- template-haskell.cabal. name: template-haskell -version: 2.16.0.0 +version: 2.17.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit 1127b30e1e0affa08f056e35ad17957b12982ba3 +Subproject commit a01843250166b5559936ba5eb81f7873e709587a ===================================== utils/ghc-cabal/ghc.mk ===================================== @@ -23,9 +23,9 @@ CABAL_CONSTRAINT := --constraint="Cabal == $(CABAL_DOTTED_VERSION)" # macros is triggered by `-hide-all-packages`, so we have to explicitly # enumerate all packages we need in scope. ifeq "$(Windows_Host)" "YES" -CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath Win32 +CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath Win32 template-haskell else -CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath unix +CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath unix template-haskell endif ghc-cabal_DIST_BINARY_NAME = ghc-cabal$(exeext0) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b934e30417a767063625494ecf135c9d6006f71 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b934e30417a767063625494ecf135c9d6006f71 You're receiving 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 15 03:31:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 14 Apr 2020 23:31:48 -0400 Subject: [Git][ghc/ghc][master] 3 commits: rts: Fix nomenclature in OVERWRITING_CLOSURE macros Message-ID: <5e9680241b3a4_61673f8198ee100c50720a3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 4 changed files: - includes/rts/storage/ClosureMacros.h - rts/LdvProfile.c - rts/PrimOps.cmm - rts/ProfHeap.c Changes: ===================================== includes/rts/storage/ClosureMacros.h ===================================== @@ -532,14 +532,15 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) #if defined(PROFILING) void LDV_recordDead (const StgClosure *c, uint32_t size); +RTS_PRIVATE bool isInherentlyUsed ( StgHalfWord closure_type ); #endif EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset /* in words */, uint32_t size /* closure size, in words */, - bool prim /* Whether to call LDV_recordDead */ + bool inherently_used USED_IF_PROFILING ); -EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size, bool prim USED_IF_PROFILING) +EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size, bool inherently_used USED_IF_PROFILING) { #if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK // see Note [zeroing slop when overwriting closures], also #8402 @@ -548,7 +549,7 @@ EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t // For LDV profiling, we need to record the closure as dead #if defined(PROFILING) - if (!prim) { LDV_recordDead(p, size); }; + if (!inherently_used) { LDV_recordDead(p, size); }; #endif for (uint32_t i = offset; i < size; i++) { @@ -559,7 +560,11 @@ EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t EXTERN_INLINE void overwritingClosure (StgClosure *p); EXTERN_INLINE void overwritingClosure (StgClosure *p) { - overwritingClosure_(p, sizeofW(StgThunkHeader), closure_sizeW(p), false); +#if defined(PROFILING) + ASSERT(!isInherentlyUsed(get_itbl(p)->type)); +#endif + overwritingClosure_(p, sizeofW(StgThunkHeader), closure_sizeW(p), + /*inherently_used=*/false); } // Version of 'overwritingClosure' which overwrites only a suffix of a @@ -572,21 +577,24 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p) EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset); EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset) { - // Set prim = true because overwritingClosureOfs is only - // ever called by - // shrinkMutableByteArray# (ARR_WORDS) - // shrinkSmallMutableArray# (SMALL_MUT_ARR_PTRS) - // This causes LDV_recordDead to be invoked. We want this - // to happen because the implementations of the above - // primops both call LDV_RECORD_CREATE after calling this, - // effectively replacing the LDV closure biography. - // See Note [LDV Profiling when Shrinking Arrays] - overwritingClosure_(p, offset, closure_sizeW(p), true); + // Since overwritingClosureOfs is only ever called by: + // + // - shrinkMutableByteArray# (ARR_WORDS) and + // + // - shrinkSmallMutableArray# (SMALL_MUT_ARR_PTRS) + // + // we can safely set inherently_used = true, which means LDV_recordDead + // won't be invoked below. Since these closures are inherenlty used we don't + // need to track their destruction. + overwritingClosure_(p, offset, closure_sizeW(p), /*inherently_used=*/true); } // Version of 'overwritingClosure' which takes closure size as argument. EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size /* in words */); EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size) { - overwritingClosure_(p, sizeofW(StgThunkHeader), size, false); +#if defined(PROFILING) + ASSERT(!isInherentlyUsed(get_itbl(p)->type)); +#endif + overwritingClosure_(p, sizeofW(StgThunkHeader), size, /*inherently_used=*/false); } ===================================== rts/LdvProfile.c ===================================== @@ -18,6 +18,37 @@ #include "RtsUtils.h" #include "Schedule.h" +bool isInherentlyUsed( StgHalfWord closure_type ) +{ + switch(closure_type) { + case TSO: + case STACK: + case MVAR_CLEAN: + case MVAR_DIRTY: + case TVAR: + case MUT_ARR_PTRS_CLEAN: + case MUT_ARR_PTRS_DIRTY: + case MUT_ARR_PTRS_FROZEN_CLEAN: + case MUT_ARR_PTRS_FROZEN_DIRTY: + case SMALL_MUT_ARR_PTRS_CLEAN: + case SMALL_MUT_ARR_PTRS_DIRTY: + case SMALL_MUT_ARR_PTRS_FROZEN_CLEAN: + case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: + case ARR_WORDS: + case WEAK: + case MUT_VAR_CLEAN: + case MUT_VAR_DIRTY: + case BCO: + case PRIM: + case MUT_PRIM: + case TREC_CHUNK: + return true; + + default: + return false; + } +} + /* -------------------------------------------------------------------------- * This function is called eventually on every object destroyed during * a garbage collection, whether it is a major garbage collection or @@ -55,33 +86,13 @@ processHeapClosureForDead( const StgClosure *c ) size = closure_sizeW(c); - switch (info->type) { - /* + /* 'inherently used' cases: do nothing. - */ - case TSO: - case STACK: - case MVAR_CLEAN: - case MVAR_DIRTY: - case TVAR: - case MUT_ARR_PTRS_CLEAN: - case MUT_ARR_PTRS_DIRTY: - case MUT_ARR_PTRS_FROZEN_CLEAN: - case MUT_ARR_PTRS_FROZEN_DIRTY: - case SMALL_MUT_ARR_PTRS_CLEAN: - case SMALL_MUT_ARR_PTRS_DIRTY: - case SMALL_MUT_ARR_PTRS_FROZEN_CLEAN: - case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: - case ARR_WORDS: - case WEAK: - case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: - case BCO: - case PRIM: - case MUT_PRIM: - case TREC_CHUNK: + */ + if(isInherentlyUsed(info->type)) return size; + switch (info->type) { /* ordinary cases: call LDV_recordDead(). */ ===================================== rts/PrimOps.cmm ===================================== @@ -158,6 +158,17 @@ stg_isMutableByteArrayPinnedzh ( gcptr mba ) jump stg_isByteArrayPinnedzh(mba); } +/* Note [LDV profiling and resizing arrays] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * As far as the LDV profiler is concerned arrays are "inherently used" which + * means we don't track their time of use and eventual destruction. We just + * assume they get used. + * + * Thus it is not necessary to call LDV_RECORD_CREATE when resizing them as we + * used to as the LDV profiler will essentially ignore arrays anyways. + */ + // shrink size of MutableByteArray in-place stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size ) // MutableByteArray# s -> Int# -> State# s -> State# s @@ -167,9 +178,7 @@ stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) + ROUNDUP_BYTES_TO_WDS(new_size))); StgArrBytes_bytes(mba) = new_size; - // See the comments in overwritingClosureOfs for an explanation - // of the interaction with LDV profiling. - LDV_RECORD_CREATE(mba); + // No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays] return (); } @@ -193,7 +202,7 @@ stg_resizzeMutableByteArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) + new_size_wds)); StgArrBytes_bytes(mba) = new_size; - LDV_RECORD_CREATE(mba); + // No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays] return (mba); } else { @@ -222,9 +231,7 @@ stg_shrinkSmallMutableArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) + new_size)); StgSmallMutArrPtrs_ptrs(mba) = new_size; - // See the comments in overwritingClosureOfs for an explanation - // of the interaction with LDV profiling. - LDV_RECORD_CREATE(mba); + // No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays] return (); } ===================================== rts/ProfHeap.c ===================================== @@ -280,6 +280,8 @@ LDV_recordDead( const StgClosure *c, uint32_t size ) uint32_t t; counter *ctr; + ASSERT(!isInherentlyUsed(get_itbl(c)->type)); + if (era > 0 && closureSatisfiesConstraints(c)) { size -= sizeofW(StgProfHeader); ASSERT(LDVW(c) != 0); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3c0f662df06500a11970fd391d0a88e081a5296...19de2fb090a25ab0d640d0cd5aef09f35e7455a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3c0f662df06500a11970fd391d0a88e081a5296...19de2fb090a25ab0d640d0cd5aef09f35e7455a0 You're receiving 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 15 07:14:16 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 15 Apr 2020 03:14:16 -0400 Subject: [Git][ghc/ghc][wip/T18008] 37 commits: simplifier: Kill off ufKeenessFactor Message-ID: <5e96b4486ed7a_6167134ebbc45093856@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18008 at Glasgow Haskell Compiler / GHC Commits: 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 76501b74 by Simon Peyton Jones at 2020-04-15T08:13:52+01:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CSE.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/Specialise.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2a6ca8d5745bf838614aff318ed2e2a48838d3e...76501b74ef73151c11766cd710283ada34205afb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2a6ca8d5745bf838614aff318ed2e2a48838d3e...76501b74ef73151c11766cd710283ada34205afb You're receiving 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 15 07:39:39 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 15 Apr 2020 03:39:39 -0400 Subject: [Git][ghc/ghc][wip/T17173] 15 commits: StgCRun: Enable unwinding only on Linux Message-ID: <5e96ba3be6a9c_61673f8198ee100c509891@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - c9f10f93 by Simon Peyton Jones at 2020-04-15T10:18:38+03:00 Do eager instantation in terms This is a first draft of a patch for #17173. It will need a proper commit message before we are done! - - - - - 04627ee4 by Simon Peyton Jones at 2020-04-15T10:18:38+03:00 Major refactor of typechecking applications Following conversation with Richard today, I have done major surgery on tcApp and friends. Fewer arguments, less plumbing, all good. I also completely killed off ir_inst. It's not as well documented as I want, yet, but I'm pushing it up for Richard's review. (This message will be replaced with a proper commit message.) - - - - - a923408a by Simon Peyton Jones at 2020-04-15T10:18:38+03:00 Wibbles, esp to error reporting - - - - - 30 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/ghc.cabal.in - ghc.mk - hadrian/src/Settings/Builders/Ghc.hs - includes/rts/storage/ClosureMacros.h - includes/rts/storage/GC.h - libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc - libraries/base/tests/T9681.stderr - libraries/exceptions - libraries/ghci/ghci.cabal.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a785c222ff5900b02cf23de0d864bd5a7de9f164...a923408abbf90f132b24074e019db5bc6a631345 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a785c222ff5900b02cf23de0d864bd5a7de9f164...a923408abbf90f132b24074e019db5bc6a631345 You're receiving 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 15 07:51:04 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 15 Apr 2020 03:51:04 -0400 Subject: [Git][ghc/ghc][wip/T17173] Final wibbles Message-ID: <5e96bce885ad2_616765c7a28509965a@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 314e8459 by Simon Peyton Jones at 2020-04-15T08:50:58+01:00 Final wibbles - - - - - 4 changed files: - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs Changes: ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -131,12 +131,12 @@ tc_poly_expr_nc (L loc expr) res_ty ; return $ L loc (mkHsWrap wrap expr') } --------------- -tcInferSigma :: LHsExpr GhcRn -> TcM TcSigmaType +tcInferSigma :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcSigmaType) -- Used by tcRnExpr to implement GHCi :type tcInferSigma le@(L loc expr) = addExprCtxt le $ setSrcSpan loc $ - do { (_, _, ty) <- tcInferApp expr - ; return ty } + do { (fun, args, ty) <- tcInferApp expr + ; return (L loc (wrapHsArgs fun args), ty) } --------------- tcInferRho, tcInferRhoNC :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcRhoType) ===================================== compiler/GHC/Tc/Gen/Expr.hs-boot ===================================== @@ -15,6 +15,8 @@ tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId) tcInferRho, tcInferRhoNC :: LHsExpr GhcRn-> TcM (LHsExpr GhcTcId, TcRhoType) +tcInferSigma :: LHsExpr GhcRn-> TcM (LHsExpr GhcTcId, TcSigmaType) + tcSyntaxOp :: CtOrigin -> SyntaxExprRn -> [SyntaxOpType] -- ^ shape of syntax operator arguments ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -28,7 +28,7 @@ where import GhcPrelude -import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferRho ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferSigma ) import GHC.Hs import GHC.Tc.Utils.Zonk @@ -409,7 +409,9 @@ tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside -- An exotic example: -- pair :: forall a. a -> forall b. b -> (a,b) -- f (pair True -> x) = ...here (x :: forall b. b -> (Bool,b)) - ; (expr',expr_ty) <- tcInferRho expr + -- + -- TEMPORARY: pending simple subsumption, use tcInferSigma + ; (expr',expr_ty) <- tcInferSigma expr -- Expression must be a function ; let expr_orig = lexprCtOrigin expr ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2489,7 +2489,7 @@ tcRnExpr hsc_env mode rdr_expr -- it might have a rank-2 type (e.g. :t runST) uniq <- newUnique ; let { fresh_it = itName uniq (getLoc rdr_expr) } ; - ((tclvl, res_ty), lie) + ((tclvl, (_tc_expr, res_ty)), lie) <- captureTopConstraints $ pushTcLevelM $ tc_infer rn_expr ; @@ -2518,8 +2518,7 @@ tcRnExpr hsc_env mode rdr_expr return (snd (normaliseType fam_envs Nominal ty)) } where - tc_infer expr | inst = do { (_, ty) <- tcInferRho expr - ; return ty } + tc_infer expr | inst = tcInferRho expr | otherwise = tcInferSigma expr -- See Note [TcRnExprMode] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/314e8459370714fbf94d294a8701f0e7866fad53 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/314e8459370714fbf94d294a8701f0e7866fad53 You're receiving 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 15 09:17:06 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 15 Apr 2020 05:17:06 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn] 18 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5e96d112845e9_6167e4e49b45104028@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 8b1c64a0 by Sebastian Graf at 2020-04-15T10:44:28+02:00 DmdAnal: Reflect precise exceptions in demand types This is part two of the "fixing precise exception" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions and, in combination with !2956, supercedes !2525. In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that is terribly unprincipled. That unprincipledness results in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is quite a misnomer and is called `mayThrowPreciseException` now. Also there is a slight chance that the IO hack was unsound before, because it assumes that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380d`. As for *how* we fixed these wrinkles: We augmented the `Divergence` lattice to a diamond with two new elements forming the middle layer: - `ExnOrDiv`: Means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. - `ConOrDiv`: Means either `Diverges` (, throws an imprecise exception) or converges. See the wiki page for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#replacing-hacks-by-principled-program-analyses - - - - - b821abb9 by Sebastian Graf at 2020-04-15T11:16:54+02:00 Fix the perf regression in T12227/T12545 But now T9233 fails because we are doing more work. Temporarily marking as accepted increase. Metric Increase: T9233 Metric Decrease: hie002 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/CallArity.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/FloatOut.hs - compiler/GHC/Core/Op/LiberateCase.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/Simplify/Utils.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4d8912eb61de6e2d5de0b6a0b656526e1662705...b821abb9cc2a0a8bc11323bbf830fd95e1aace85 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4d8912eb61de6e2d5de0b6a0b656526e1662705...b821abb9cc2a0a8bc11323bbf830fd95e1aace85 You're receiving 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 15 12:12:33 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 15 Apr 2020 08:12:33 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17760-runRW Message-ID: <5e96fa31860cb_6167136dfb9c51121de@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T17760-runRW at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17760-runRW You're receiving 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 15 13:05:11 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 15 Apr 2020 09:05:11 -0400 Subject: [Git][ghc/ghc][wip/T17173] Final wibbles Message-ID: <5e97068735ea2_616776d1c74512078d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 27399067 by Simon Peyton Jones at 2020-04-15T14:04:02+01:00 Final wibbles Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 4 changed files: - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs Changes: ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -131,12 +131,12 @@ tc_poly_expr_nc (L loc expr) res_ty ; return $ L loc (mkHsWrap wrap expr') } --------------- -tcInferSigma :: LHsExpr GhcRn -> TcM TcSigmaType +tcInferSigma :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcSigmaType) -- Used by tcRnExpr to implement GHCi :type tcInferSigma le@(L loc expr) = addExprCtxt le $ setSrcSpan loc $ - do { (_, _, ty) <- tcInferApp expr - ; return ty } + do { (fun, args, ty) <- tcInferApp expr + ; return (L loc (wrapHsArgs fun args), ty) } --------------- tcInferRho, tcInferRhoNC :: LHsExpr GhcRn -> TcM (LHsExpr GhcTc, TcRhoType) ===================================== compiler/GHC/Tc/Gen/Expr.hs-boot ===================================== @@ -15,6 +15,8 @@ tcExpr :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTcId) tcInferRho, tcInferRhoNC :: LHsExpr GhcRn-> TcM (LHsExpr GhcTcId, TcRhoType) +tcInferSigma :: LHsExpr GhcRn-> TcM (LHsExpr GhcTcId, TcSigmaType) + tcSyntaxOp :: CtOrigin -> SyntaxExprRn -> [SyntaxOpType] -- ^ shape of syntax operator arguments ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -28,7 +28,7 @@ where import GhcPrelude -import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferRho ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcSyntaxOp, tcSyntaxOpGen, tcInferSigma ) import GHC.Hs import GHC.Tc.Utils.Zonk @@ -409,7 +409,9 @@ tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside -- An exotic example: -- pair :: forall a. a -> forall b. b -> (a,b) -- f (pair True -> x) = ...here (x :: forall b. b -> (Bool,b)) - ; (expr',expr_ty) <- tcInferRho expr + -- + -- TEMPORARY: pending simple subsumption, use tcInferSigma + ; (expr',expr_ty) <- tcInferSigma expr -- Expression must be a function ; let expr_orig = lexprCtOrigin expr ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2489,7 +2489,7 @@ tcRnExpr hsc_env mode rdr_expr -- it might have a rank-2 type (e.g. :t runST) uniq <- newUnique ; let { fresh_it = itName uniq (getLoc rdr_expr) } ; - ((tclvl, res_ty), lie) + ((tclvl, (_tc_expr, res_ty)), lie) <- captureTopConstraints $ pushTcLevelM $ tc_infer rn_expr ; @@ -2518,8 +2518,7 @@ tcRnExpr hsc_env mode rdr_expr return (snd (normaliseType fam_envs Nominal ty)) } where - tc_infer expr | inst = do { (_, ty) <- tcInferRho expr - ; return ty } + tc_infer expr | inst = tcInferRho expr | otherwise = tcInferSigma expr -- See Note [TcRnExprMode] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27399067b5ff7c335e5bf1f2bc7490f8f8e5027d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27399067b5ff7c335e5bf1f2bc7490f8f8e5027d You're receiving 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 15 15:06:00 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 15 Apr 2020 11:06:00 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 1226 commits: gitlab-ci: Add Windows full build during the nightly pipeline Message-ID: <5e9722d8b114_6167e4e49b45135293@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: d5055248 by Ben Gamari at 2019-08-22T09:25:08-04:00 gitlab-ci: Add Windows full build during the nightly pipeline - - - - - a33bad2d by Sylvain Henry at 2019-08-22T09:25:47-04:00 Doc: add Haddocks for quotRemWord2 primop - - - - - 605bce26 by James Foster at 2019-08-22T18:47:20-04:00 Add documentation for Hadrian expressions This commit adds documentation on Hadrian's 'Expr' type and references the documentation in hadrian/README.md - - - - - 8f32d2bc by TDecki at 2019-08-22T18:47:57-04:00 base: Reintroduce fusion for scanr While avoiding #16943. - - - - - c3e26ab3 by Ömer Sinan Ağacan at 2019-08-22T22:19:26-04:00 Remove special case in SRT generation with -split-sections Previously we were using an empty ModuleSRTInfo for each Cmm group with -split-section. As far as I can see this has no benefits, and simplifying this makes another patch simpler (!1304). We also remove some outdated comments: we no longer generate one module-level SRT. - - - - - a8300520 by Ömer Sinan Ağacan at 2019-08-23T12:04:15+03:00 Make non-streaming LLVM and C backends streaming This adds a Stream.consume function, uses it in LLVM and C code generators, and removes the use of Stream.collect function which was used to collect streaming Cmm generation results into a list. LLVM and C backends now properly use streamed Cmm generation, instead of collecting Cmm groups into a list before generating LLVM/C code. - - - - - 47070144 by Andreas Klebinger at 2019-08-23T19:26:42-04:00 Use variable length encoding for Binary instances. Use LEB128 encoding for Int/Word variants. This reduces the size of interface files significantly. (~19%). Also includes a few small optimizations to make unboxing work better that I have noticed while looking at the core. - - - - - cff44d86 by Sergei Trofimovich at 2019-08-23T19:27:21-04:00 configure.ac: fix '--disable-dwarf-debug' Before the change ./configure --disable-dwarf-debug enabled DWARF debugging unconditionally. This happened due to use of 5-argument form of `AC_ARG_ENABLE` without actually checking the passed `$enableval` parameter: ``` AC_ARG_ENABLE(dwarf-unwind, [AC_HELP_STRING([--enable-dwarf-unwind], [Enable DWARF unwinding support in the runtime system via elfutils' libdw [default=no]])], [AC_CHECK_LIB(dw, dwfl_attach_state, [UseLibdw=YES], [AC_MSG_ERROR([Cannot find system libdw (required by --enable-dwarf-unwind)])])] [UseLibdw=NO] ) ``` Note: - `[UseLibdw=NO]` is called when `--{enable,disable}-dwarf-unwind` is not passed at all as a parameter (ok). - `[AC_CHECK_LIB(dw, dwfl_attach_state, [UseLibdw=YES],` is called for both: * `--enable-dwarf-unwind` being passed: `$enableval = "yes"` (ok). * --disable-dwarf-unwind` being passed: `$enableval = "no"` (bad). The change is to use 3-argument `AC_ARG_ENABLE` and check for passed value as `"$enable_dwarf_unwind" = "yes"`. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 10763ce0 by Ömer Sinan Ağacan at 2019-08-27T10:45:02+03:00 Some more documentation for typePrimRep1 stuff [skip ci] - - - - - 89487be2 by Ömer Sinan Ağacan at 2019-08-27T15:21:50-04:00 Some tweaks in GHC.Compact haddocks - - - - - ee2fad9e by Andreas Klebinger at 2019-08-27T15:22:28-04:00 Remove redundant OPTIONS_GHC in BlockLayout.hs - - - - - 1c7ec449 by Ömer Sinan Ağacan at 2019-08-28T12:51:12+03:00 Return results of Cmm streams in backends This generalizes code generators (outputAsm, outputLlvm, outputC, and the call site codeOutput) so that they'll return the return values of the passed Cmm streams. This allows accumulating data during Cmm generation and returning it to the call site in HscMain. Previously the Cmm streams were assumed to return (), so the code generators returned () as well. This change is required by !1304 and !1530. Skipping CI as this was tested before and I only updated the commit message. [skip ci] - - - - - a308b435 by Sebastian Graf at 2019-08-28T11:33:49-04:00 Fix #17112 The `mkOneConFull` function of the pattern match checker used to try to guess the type arguments of the data type's type constructor by looking at the ambient type of the match. This doesn't work well for Pattern Synonyms, where the result type isn't even necessarily a TyCon application, and it shows in #11336 and #17112. Also the effort seems futile; why try to try hard when the type checker has already done the hard lifting? After this patch, we instead supply the type constructors arguments as an argument to the function and lean on the type-annotated AST. - - - - - 137c24e1 by Ryan Scott at 2019-08-28T22:36:40-04:00 Balance parentheses in GHC 8.10.1 release notes [ci skip] - - - - - 66282ba5 by luca at 2019-08-28T22:37:19-04:00 Remove Unused flag -ddump-shape [skip ci] - - - - - bf9dfe1c by Ömer Sinan Ağacan at 2019-08-29T04:28:35-04:00 Fix LLVM version check yet again There were two problems with LLVM version checking: - The parser would only parse x and x.y formatted versions. E.g. 1.2.3 would be rejected. - The version check was too strict and would reject x.y formatted versions. E.g. when we support version 7 it'd reject 7.0 ("LLVM version 7.0") and only accept 7 ("LLVM version 7"). We now parse versions with arbitrarily deep minor numbering (x.y.z.t...) and accept versions as long as the major version matches the supported version (e.g. 7.1, 7.1.2, 7.1.2.3 ...). - - - - - fc746e98 by Ben Gamari at 2019-08-29T04:29:13-04:00 gitlab-ci: Fix URL of Darwin's cabal-install tarball This was inadvertently referring to the cabal-install-latest/ directory which is volatile. - - - - - 304067a0 by Ömer Sinan Ağacan at 2019-08-29T09:38:25-04:00 Small optimization in the SRT algorithm Noticed by @simonmar in !1362: If the srtEntry is Nothing, then it should be safe to omit references to this SRT from other SRTs, even if it is a static function. When updating SRT map we don't omit references to static functions (see Note [Invalid optimisation: shortcutting]), but there's no reason to add an SRT entry for a static function if the function is not CAFFY. (Previously we'd add SRT entries for static functions even when they're not CAFFY) Using 9151b99e I checked sizes of all SRTs when building GHC and containers: - GHC: 583736 (HEAD), 581695 (this patch). 2041 less SRT entries. - containers: 2457 (HEAD), 2381 (this patch). 76 less SRT entries. - - - - - 78afc2c9 by Sergei Trofimovich at 2019-08-30T06:14:44-04:00 configure.ac: add --enable-numa switch Before the change ./configure detected numa support automatically withoun a nice way to disable autodetection. The change adds `--enable-numa` / `--disable-numa` switch to override the default. If `--enable-numa` is passed and `libnuma` is not present then configure will fail. Reported-by: Sergey Alirzaev Bug: https://github.com/gentoo-haskell/gentoo-haskell/issues/955 Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - c0956c14 by Vladislav Zavialov at 2019-08-30T06:15:21-04:00 Remove HsUtils/userHsLTyVarBndrs This patch removes 'userHsLTyVarBndrs' and 'userHsTyVarBndrs' from HsUtils. These helper functions were not used anywhere. - - - - - 7e6aeb13 by Eric Wolf at 2019-08-31T10:25:39+02:00 Add additional step to T16804 Add another small test step Use the same identifier name in different scopes and see, if ':uses' handles that. Add another test step to check wether local bindings with the same identifier name might get confused Add easier to understand test output Fix annotated lines from file correctly - - - - - e56251f6 by Ömer Sinan Ağacan at 2019-08-31T17:55:13-04:00 Remove redundant special case in STG pretty-printer This special case existed for no reason, and made things inconsistent. Before Boolean.$bT :: Boolean.Boolean [GblId, Str=m, Unf=OtherCon []] = CAF_ccs \ u [] Boolean.$bT1; After Boolean.$bF :: Boolean.Boolean [GblId, Str=m, Unf=OtherCon []] = \u [] Boolean.$bF1; The cost-centre is now hidden when not profiling, as is the case with other types of closures. - - - - - cfab4abe by Gershom Bazerman at 2019-09-01T00:34:05-04:00 cap max stack size at 32 bit limit (#17019) - - - - - 9acba780 by John Ericson at 2019-09-01T22:44:45-04:00 Use C99 Fixed width types to avoid hack in base's configure Define MD5Context in terms of `uint*_t` and don't use `HsFFI.h`. - - - - - 11679e5b by Ömer Sinan Ağacan at 2019-09-02T13:17:49+03:00 Few tweaks in -ddump-debug output, minor refactoring - Fixes crazy indentation in -ddump-debug output - We no longer dump empty sections in -ddump-debug when a code block does not have any generated debug info - Minor refactoring in Debug.hs and AsmCodeGen.hs - - - - - f96d57b8 by John Ericson at 2019-09-05T18:50:19-04:00 Make the C-- O and C types constructors with DataKinds The tightens up the kinds a bit. I use type synnonyms to avoid adding promotion ticks everywhere. - - - - - b55ee979 by John Ericson at 2019-09-05T18:50:56-04:00 Make sure all boolean settings entries use `YES` / `NO` Some where using `True` / `False`, a legacy of when they were in `Config.hs`. See #16914 / d238d3062a9858 for a similar problem. Also clean up the configure variables names for consistency and clarity while we're at it. "Target" makes clear we are talking about outputted code, not where GHC itself runs. - - - - - 821bece9 by Ömer Sinan Ağacan at 2019-09-07T04:50:21-04:00 Minor refactoring in deriveConstants Mainly we now generate this data PlatformConstants = PlatformConstants { pc_CONTROL_GROUP_CONST_291 :: Int, pc_STD_HDR_SIZE :: Int, pc_PROF_HDR_SIZE :: Int, pc_BLOCK_SIZE :: Int, } instead of data PlatformConstants = PlatformConstants { pc_platformConstants :: () , pc_CONTROL_GROUP_CONST_291 :: Int , pc_STD_HDR_SIZE :: Int , pc_PROF_HDR_SIZE :: Int , pc_BLOCK_SIZE :: Int ... } The first field has no use and according to (removed) comments it was to make code generator's work easier.. if anything this version is simpler because it has less repetition (the commas in strings are gone). - - - - - b0fdd7fe by Alp Mestanogullari at 2019-09-07T04:50:59-04:00 hadrian: fix _build/ghc-stage1 to make it callable from any directory - - - - - 51379b89 by Ömer Sinan Ağacan at 2019-09-08T21:40:32-04:00 Add a new flag -dno-typeable-binds for debugging See the user manual entry -- this helps when debugging as generated Core gets smaller without these bindings. - - - - - d0b45ac6 by Moritz Kiefer at 2019-09-08T21:41:12-04:00 Fix GHC version guard for Int32Rep/Word32Rep Those constructors have been added after GHC 8.8. The version guards in `binary` are correct, see https://github.com/kolmodin/binary/pull/167/files. - - - - - 4cf91d1a by Daniel Gröber at 2019-09-09T05:42:33-04:00 Use lazyness for FastString's z-encoding memoization Having an IORef in FastString to memoize the z-encoded version is unecessary because there is this amazing thing Haskell can do natively, it's called "lazyness" :) We simply remove the UNPACK and strictness annotations from the constructor field corresponding to the z-encoding, making it lazy, and store the (pure) z-encoded string there. The only complication here is 'hasZEncoding' which allows cheking if a z-encoding was computed for a given string. Since this is only used for compiler performance statistics though it's not actually necessary to have the current per-string granularity. Instead I add a global IORef counter to the FastStringTable and use unsafePerformIO to increment the counter whenever a lazy z-encoding is forced. - - - - - f5e2fde4 by Daniel Gröber at 2019-09-09T05:42:33-04:00 Update FastString docstrings 1) FastStrings are always UTF-8 encoded now. 2) Clarify what is meant by "hashed" 3) Add mention of lazy z-enc - - - - - 270fbe85 by Ryan Scott at 2019-09-09T05:43:12-04:00 Replace queryCygwinTerminal with Win32's isMinTTYHandle `SysTools.Terminal.queryCygwinTerminal` now exists in the `Win32` library under the name `isMinTTYHandle` since `Win32-2.5.0.0`. (GHC 8.4.4 ships with `Win32-2.6.1.0`, so this is well within GHC's support window.) We can therefore get replace `queryCygwinTerminal` with `isMinTTYHandle` and delete quite a bit of code from `SysTools.Terminal` in the process. Along the way I needed to replace some uses of `#if defined x` with `#if defined(x)` to please the CI linters. - - - - - 447864a9 by Sylvain Henry at 2019-09-10T00:04:50+02:00 Module hierarchy: StgToCmm (#13009) Add StgToCmm module hierarchy. Platform modules that are used in several other places (NCG, LLVM codegen, Cmm transformations) are put into GHC.Platform. - - - - - 60c26403 by Niklas Hambüchen at 2019-09-11T09:44:23-04:00 linker: Move -optl flags to end of linker invocation. Until now, giving `-optl` linker flags to `ghc` on the command line placed them in the wrong place in the `ld` command line: They were given before all the Haskell libararies, when they should appear after. Background: Most linkers like `ld.bfd` and `ld.gold`, but not the newer LLVM `lld`, work in a way where the order of `-l` flags given matters; earlier `-lmylib1` flags are supposed to create "holes" for linker symbols that are to be filled with later `lmylib2` flags that "fill the holes" for these symbols. As discovered in https://github.com/haskell/cabal/pull/5451#issuecomment-518001240, the `-optl` flags appeared before e.g. the -lHStext-1.2.3.1 -lHSbinary-0.8.6.0 -lHScontainers-0.6.0.1 flags that GHC added at the very end. Haskell libraries typically depend on C libraries, so `-lHS*` flags will create holes for the C libraries to fill in, but that only works when those libraries' `-l` flags are given **after** the `-lHS*` flags; until now they were given before, which was wrong. This meant that Cabal's `--ld-options` flag and `ld-options` `.cabal` file field were pretty ineffective, unless you used the `--ld-option=--start-group` hack as (https://github.com/haskell/cabal/pull/5451#issuecomment-406761676) that convinces the classical linkers to not be dependent on the order of linker flags given. This commit fixes the problem by simply flipping the order, putting `-optl` flags at the end, after Haskell libraries. The code change is effectively only `args1 ++ args` -> `args ++ args1` but the commit also renames the variables for improved clarity. Simple way to test it: ghc --make Main.hs -fforce-recomp -v -optl-s on a `Main.hs` like: import qualified Data.Set as Set main = print $ Set.fromList "hello" - - - - - 7032a913 by John Ericson at 2019-09-11T09:45:02-04:00 Remove COMPILING_GHC It is no longer used. I guess we are sharing fewer headers with the RTS than the comment claims. That's a relief! - - - - - 58569a5b by Peter Trommler at 2019-09-11T09:45:47-04:00 testsuite: check for RTS linker Fixes #16833 - - - - - df6fbe03 by Luke Lau at 2019-09-11T09:46:36-04:00 Bump Hadrian's QuickCheck dependency - - - - - d9e637df by John Ericson at 2019-09-11T09:47:26-04:00 Remove dead `ncgDebugIsOn` and `NCG_DEBUG` Haven't been used since 16206a6603e87e15d61c57456267c5f7ba68050e. - - - - - 7ef6fe8f by Ben Gamari at 2019-09-11T09:48:03-04:00 SetLevels: Fix potential panic in lvlBind 3b31a94d introduced a use of isUnliftedType which can panic in the case of levity-polymorphic types. Fix this by introducing mightBeUnliftedType which returns whether the type is *guaranteed* to be lifted. - - - - - c76cc0c6 by Ömer Sinan Ağacan at 2019-09-11T19:40:06-04:00 Refactor bad coercion checking in a few places We do bad coercion checking in a few places in the compiler, but they all checked it differently: - CoreToStg.coreToStgArgs: Disallowed lifted-to-unlifted, disallowed changing prim reps even when the sizes are the same. - StgCmmExpr.cgCase: Checked primRepSlot equality. This disallowed Int to Int64 coercions on 64-bit systems (and Int to Int32 on 32-bit) even though those are fine. - CoreLint: Only place where we do this right. Full rules are explained in Note [Bad unsafe coercion]. This patch implements the check explained in Note [Bad unsafe coercion] in CoreLint and uses it in CoreToStg.coreToStgArgs and StgCmmExpr.cgCase. This fixes #16952 and unblocks !1381 (which fixes #16893). This is the most conservative and correct change I came up with that fixes #16952. One remaining problem with coercion checking is that it's currently done in seemingly random places. What's special about CoreToStg.coreToStgArgs and StgCmmExpr.cgCase? My guess is that adding assertions to those places caught bugs before so we left assertions in those places. I think we should remove these assertions and do coercion checking in CoreLint and StgLint only (#17041). - - - - - 3a7d3923 by Tamar Christina at 2019-09-11T19:40:53-04:00 Windows: make openTempFile fully atomic. - - - - - 98b0d6ee by Pranay Sashank at 2019-09-12T04:52:33-04:00 Print the correct system memory in use with +RTS -s (#17158) Use `stats.max_mem_in_use_bytes` to print the memory usage instead of `stats.max_live_bytes` which prints maximum residency. Fixes (#17158). - - - - - a06629b4 by John Ericson at 2019-09-12T04:53:13-04:00 Do not throw away backpack instantiations for module lookup cache Currently, there is only one home package so this probably doesn't matter. But if we support multiple home packages, they could differ only in arguments (same indef component being applied). It looks like it used to be this way before 4e8a0607140b23561248a41aeaf837224aa6315b, but that commit doesn't seem to comment on this change in the particular. (It's main purpose is creating the InstalledUnitId and recategorizing the UnitId expressions accordingly.) Trying this as a separate commit for testing purposes. I leave it to others to decide whether this is a good change on its own. - - - - - 09fa5654 by John Ericson at 2019-09-12T04:53:51-04:00 Remove unused `#include`s from parser/cutils.c Looks like these have been unused since 7c665f9ce0980ee7c81a44c8f861686395637453. - - - - - 2b37a79d by Sebastian Graf at 2019-09-12T14:05:29-04:00 Bump Cabal submodule to 3.1 ------------------------- Metric Increase: haddock.Cabal T4029 ------------------------- - - - - - 86753475 by Ningning Xie at 2019-09-12T14:06:07-04:00 Fix StandaloneDeriving If I understand correctly, `deriving instance _ => Eq (Foo a)` is equivalent to `data Foo a deriving Eq`, rather than `data Foo a deriving Foo`. - - - - - a733002a by Ben Gamari at 2019-09-13T03:09:47-04:00 Update mailmap - - - - - 5b64aee2 by Simon Peyton Jones at 2019-09-13T03:10:26-04:00 Fix scoping of implicit parameters There was an outright bug in TcInteract.solveOneFromTheOther which meant that we did not always pick the innermost implicit parameter binding, causing #17104. The fix is easy, just a rearrangement of conditional tests - - - - - 47b12660 by Tamar Christina at 2019-09-13T03:11:06-04:00 Windows: Fix hsc2hs non-deterministic failures. - - - - - e3a7592b by Alp Mestanogullari at 2019-09-13T03:11:50-04:00 Add a test to make sure we don't regress on #17140 in the future - - - - - 6f3cd50e by Zubin Duggal at 2019-09-13T11:24:51-04:00 Explain how to update HieAst [skip ci] - - - - - 71428a43 by Zubin Duggal at 2019-09-13T11:24:51-04:00 Address review comments [skip CI] - - - - - ccb4e646 by John Ericson at 2019-09-13T11:25:29-04:00 Compiler should always get fingerprinting impl from base 07ee15915d5a0d6d1aeee137541eec6e9c153e65 started the transition, but the job was never finished. - - - - - c45c89d6 by Ben Gamari at 2019-09-13T11:26:05-04:00 gitlab: Add issue template for documentation issues Fixes #17180. - - - - - a0e220b7 by John Ericson at 2019-09-13T11:26:43-04:00 Remove empty NCG.h - - - - - 046ca133 by Andrew Martin at 2019-09-13T15:43:16-04:00 Add predicates for testing if IOError is ResourceVanished. This adds isResourceVanished, resourceVanishedErrorType, and isResourceVanishedErrorType to System.IO.Error, resolving #14730. - - - - - bd079345 by taylorfausak at 2019-09-14T06:25:27-04:00 Fix CONLIKE typo - - - - - cf7e78a3 by Ben Gamari at 2019-09-15T23:46:36-04:00 Rename GHC.StgToCmm.Con -> GHC.StgToCmm.DataCon Incredibly, Windows disallows the manipulation of any file matching Con(\..*)?. The `GHC.StgToCmm.Con` was introduced in the renamings in 447864a9, breaking the Windows build. Work around this by renaming it to `GHC.StgToCmm.DataCon` Fixes #17187. - - - - - 7208160d by Sylvain Henry at 2019-09-15T23:47:22-04:00 Fix Hadrian build with Stack (#17189) Broken by 2b37a79d61e9b3787873dc9f7458ef2bde4809b0 - - - - - b5ae3868 by Sylvain Henry at 2019-09-16T13:32:22-04:00 Allow validation with Hadrian built with Stack [skip ci] - - - - - 7915afc6 by Sebastian Graf at 2019-09-16T13:33:05-04:00 Encode shape information in `PmOracle` Previously, we had an elaborate mechanism for selecting the warnings to generate in the presence of different `COMPLETE` matching groups that, albeit finely-tuned, produced wrong results from an end user's perspective in some cases (#13363). The underlying issue is that at the point where the `ConVar` case has to commit to a particular `COMPLETE` group, there's not enough information to do so and the status quo was to just enumerate all possible complete sets nondeterministically. The `getResult` function would then pick the outcome according to metrics defined in accordance to the user's guide. But crucially, it lacked knowledge about the order in which affected clauses appear, leading to the surprising behavior in #13363. In !1010 we taught the term oracle to reason about literal values a variable can certainly not take on. This MR extends that idea to `ConLike`s and thereby fixes #13363: Instead of committing to a particular `COMPLETE` group in the `ConVar` case, we now split off the matching constructor incrementally and record the newly covered case as a refutable shape in the oracle. Whenever the set of refutable shapes covers any `COMPLETE` set, the oracle recognises vacuosity of the uncovered set. This patch goes a step further: Since at this point the information in value abstractions is merely a cut down representation of what the oracle knows, value abstractions degenerate to a single `Id`, the semantics of which is determined by the oracle state `Delta`. Value vectors become lists of `[Id]` given meaning to by a single `Delta`, value set abstractions (of which the uncovered set is an instance) correspond to a union of `Delta`s which instantiate the same `[Id]` (akin to models of formula). Fixes #11528 #13021, #13363, #13965, #14059, #14253, #14851, #15753, #17096, #17149 ------------------------- Metric Decrease: ManyAlternatives T11195 ------------------------- - - - - - ae4415b9 by Matthew Pickering at 2019-09-17T19:21:10-04:00 eventlog: Add biographical and retainer profiling traces This patch adds a new eventlog event which indicates the start of a biographical profiler sample. These are different to normal events as they also include the timestamp of when the census took place. This is because the LDV profiler only emits samples at the end of the run. Now all the different profiling modes emit consumable events to the eventlog. - - - - - 9c21b2fd by Richard Eisenberg at 2019-09-17T19:22:00-04:00 Fix #13571 by adding an extension flag check Test case: indexed-types/should_fail/T13571 - - - - - 8039b125 by Simon Peyton Jones at 2019-09-17T19:22:50-04:00 Comments only - - - - - 1c3af277 by Simon Peyton Jones at 2019-09-17T19:23:37-04:00 Improve error message for out-of-scope variables + VTA As #13834 and #17150 report, we get a TERRIBLE error message when you have an out of scope variable applied in a visible type application: (outOfScope @Int True) This very simple patch improves matters. See TcExpr Note [VTA for out-of-scope functions] - - - - - c77fc3b2 by John Ericson at 2019-09-17T19:24:20-04:00 Deduplicate `HaskellMachRegs.h` and `RtsMachRegs.h` headers Until 0472f0f6a92395d478e9644c0dbd12948518099f there was a meaningful host vs target distinction (though it wasn't used right, in genapply). After that, they did not differ in meaningful ways, so it's best to just only keep one. - - - - - c3eaaca6 by Simon Peyton Jones at 2019-09-19T09:03:19-04:00 Add a missing update of sc_hole_ty (#16312) In simplCast I totally failed to keep the sc_hole_ty field of ApplyToTy (see Note [The hole type in ApplyToTy]) up to date. When a cast goes by, of course the hole type changes. Amazingly this has not bitten us before, but #16312 finally triggered it. Fortunately the fix is simple. Fixes #16312. - - - - - de1723b2 by Ben Gamari at 2019-09-19T09:03:19-04:00 Simplify: Lazy pattern match - - - - - d9c6b86e by Richard Eisenberg at 2019-09-19T09:04:03-04:00 Refactor kindGeneralize and friends This commit should have no change in behavior.(*) The observation was that Note [Recipe for checking a signature] says that every metavariable in a type-checked type must either (A) be generalized (B) be promoted (C) be zapped. Yet the code paths for doing these were all somewhat separate. This led to some steps being skipped. This commit shores this all up. The key innovation is TcHsType.kindGeneralizeSome, with appropriate commentary. This commit also sets the stage for #15809, by turning the WARNing about bad level-numbers in generalisation into an ASSERTion. The actual fix for #15809 will be in a separate commit. Other changes: * zonkPromoteType is now replaced by kindGeneralizeNone. This might have a small performance degradation, because zonkPromoteType zonked and promoted all at once. The new code path promotes first, and then zonks. * A call to kindGeneralizeNone was added in tcHsPartialSigType. I think this was a lurking bug, because it did not follow Note [Recipe for checking a signature]. I did not try to come up with an example showing the bug. This is the (*) above. Because of this change, there is an error message regression in partial-sigs/should_fail/T14040a. This problem isn't really a direct result of this refactoring, but is a symptom of something deeper. See #16775, which addresses the deeper problem. * I added a short-cut to quantifyTyVars, in case there's nothing to quantify. * There was a horribly-outdated Note that wasn't referred to. Gone now. * While poking around with T14040a, I discovered a small mistake in the Coercion.simplifyArgsWorker. Easy to fix, happily. * See new Note [Free vars in coercion hole] in TcMType. Previously, we were doing the wrong thing when looking at a coercion hole in the gather-candidates algorithm. Fixed now, with lengthy explanation. Metric Decrease: T14683 - - - - - f594a68a by Richard Eisenberg at 2019-09-19T09:04:03-04:00 Use level numbers for generalisation This fixes #15809, and is covered in Note [Use level numbers for quantification] in TcMType. This patch removes the "global tyvars" from the environment, a nice little win. - - - - - c675d08f by Richard Eisenberg at 2019-09-19T09:04:03-04:00 Test #17077. - - - - - 912afaf4 by Ben Gamari at 2019-09-19T09:04:39-04:00 CoreUtils: Use mightBeUnliftedType in exprIsTopLevelBindable Also add reference from isUnliftedType to mightBeUnliftedType. - - - - - baf47661 by Sebastian Graf at 2019-09-19T09:05:20-04:00 Extract PmTypes module from PmExpr and PmOracle Apparently ghc-lib-parser's API blew up because the newly induced cyclic dependency between TcRnTypes and PmOracle pulled in the other half of GHC into the relevant strongly-connected component. This patch arranges it so that PmTypes exposes mostly data type definitions and type class instances to be used within PmOracle, without importing the any of the possibly offending modules DsMonad, TcSimplify and FamInst. - - - - - 2a8867cf by Sebastian Graf at 2019-09-19T09:05:58-04:00 Add a regression test for #11822 The particular test is already fixed, but the issue seems to have multiple different test cases lumped together. - - - - - 52173990 by Ben Gamari at 2019-09-19T09:06:36-04:00 testsuite: Add testcase for #17206 - - - - - b3e5c731 by Alp Mestanogullari at 2019-09-19T21:42:17-04:00 ErrUtils: split withTiming into withTiming and withTimingSilent 'withTiming' becomes a function that, when passed '-vN' (N >= 2) or '-ddump-timings', will print timing (and possibly allocations) related information. When additionally built with '-eventlog' and executed with '+RTS -l', 'withTiming' will also emit both 'traceMarker' and 'traceEvent' events to the eventlog. 'withTimingSilent' on the other hand will never print any timing information, under any circumstance, and will only emit 'traceEvent' events to the eventlog. As pointed out in !1672, 'traceMarker' is better suited for things that we might want to visualize in tools like eventlog2html, while 'traceEvent' is better suited for internal events that occur a lot more often and that we don't necessarily want to visualize. This addresses #17138 by using 'withTimingSilent' for all the codegen bits that are expressed as a bunch of small computations over streams of codegen ASTs. - - - - - 4853d962 by Ben Gamari at 2019-09-19T21:42:55-04:00 users guide: Fix link to let generalization blog post Fixes #17200. - - - - - 51192964 by Sylvain Henry at 2019-09-20T05:14:34-04:00 Module hierarchy: Hs (#13009) Add GHC.Hs module hierarchy replacing hsSyn. Metric Increase: haddock.compiler - - - - - 2f8ce45a by Ben Gamari at 2019-09-20T05:15:11-04:00 testsuite: Add test for #17202 - - - - - f257bf73 by Matthew Pickering at 2019-09-20T05:15:52-04:00 hadrian/ghci.sh: Enable building in parallel - - - - - 070f7b85 by Matthew Pickering at 2019-09-20T05:15:52-04:00 Remove trailing whitespace - - - - - 5390b553 by Matthew Pickering at 2019-09-20T05:15:52-04:00 Pass -j to ghc-in-ghci CI job - - - - - 1b7e1d31 by John Ericson at 2019-09-20T05:16:36-04:00 Remove pointless partiality in `Parser.ajs` - - - - - 17554248 by Simon Peyton Jones at 2019-09-20T10:50:21+01:00 Fix PmOracle.addVarCoreCt in-scope set PmOracle.addVarCoreCt was giving a bogus (empty) in-scope set to exprIsConApp_maybe, which resulted in a substitution-invariant failure (see MR !1647 discussion). This patch fixes it, by taking the free vars of the expression. - - - - - 0dad81ca by Simon Peyton Jones at 2019-09-20T10:50:21+01:00 Fix bogus type of case expression Issue #17056 revealed that we were sometimes building a case expression whose type field (in the Case constructor) was bogus. Consider a phantom type synonym type S a = Int and we want to form the case expression case x of K (a::*) -> (e :: S a) We must not make the type field of the Case constructor be (S a) because 'a' isn't in scope. We must instead expand the synonym. Changes in this patch: * Expand synonyms in the new function CoreUtils.mkSingleAltCase. * Use mkSingleAltCase in MkCore.wrapFloat, which was the proximate source of the bug (when called by exprIsConApp_maybe) * Use mkSingleAltCase elsewhere * Documentation CoreSyn new invariant (6) in Note [Case expression invariants] CoreSyn Note [Why does Case have a 'Type' field?] CoreUtils Note [Care with the type of a case expression] * I improved Core Lint's error reporting, which was pretty confusing in this case, because it didn't mention that the offending type was the return type of a case expression. * A little bit of cosmetic refactoring in CoreUtils - - - - - 1ea8c451 by Sebastian Graf at 2019-09-21T09:52:34-04:00 PredType for type constraints in the pattern match checker instead of EvVar Using EvVars for capturing type constraints implied side-effects in DsM when we just wanted to *construct* type constraints. But giving names to type constraints is only necessary when passing Givens to the type checker, of which the majority of the pattern match checker should be unaware. Thus, we simply generate `newtype TyCt = TyCt PredType`, which are nicely stateless. But at the same time this means we have to allocate EvVars when we want to query the type oracle! So we keep the type oracle state as `newtype TyState = TySt (Bag EvVar)`, which nicely makes a distinction between new, unchecked `TyCt`s and the inert set in `TyState`. - - - - - ded96fb3 by Ömer Sinan Ağacan at 2019-09-21T09:53:29-04:00 Document MIN_PAYLOAD_SIZE and mark-compact GC mark bits This updates the documentation of the MIN_PAYLOAD_SIZE constant and adds a new Note [Mark bits in mark-compact collector] explaning why the mark-compact collector uses two bits per objet and why we need MIN_PAYLOAD_SIZE. - - - - - a7867c79 by Sebastian Graf at 2019-09-21T14:56:58+01:00 Get rid of PmFake The pattern match oracle can now cope with the abundance of information that ViewPatterns, NPlusKPats, overloaded lists, etc. provide. No need to have PmFake anymore! Also got rid of a spurious call to `allCompleteMatches`, which we used to call *for every constructor* match. Naturally this blows up quadratically for programs like `ManyAlternatives`. ------------------------- Metric Decrease: ManyAlternatives Metric Increase: T11822 ------------------------- - - - - - fa66e3e5 by Alp Mestanogullari at 2019-09-21T23:31:08-04:00 Fix haddocks for marker events in Debug.Trace - - - - - da12da79 by Daniel Gröber at 2019-09-22T14:34:56+02:00 rts: retainer: Remove cStackSize debug counter This can only ever be one since 5f1d949ab9 ("Remove explicit recursion in retainer profiling"), so it's pointless. - - - - - 3ebaa4b5 by Daniel Gröber at 2019-09-22T15:17:53+02:00 rts: Remove bitrotten retainer debug code The `defined(DEBUG_RETAINER) == true` branch doesn't even compile anymore because 1) retainerSet was renamed to RetainerSet and 2) even if I fix that the context in Rts.h seems to have changed such that it's not in scope. If 3) I fix that 'flip' is still not in scope :) At that point I just gave up. - - - - - 63023dc2 by Daniel Gröber at 2019-09-22T15:18:09+02:00 rts: Fix outdated references to 'ldvTime' This got renamed to 'era' in dbef766ce7 ("[project @ 2001-11-26 16:54:21 by simonmar] Profiling cleanup"). - - - - - ead05f80 by Daniel Gröber at 2019-09-22T15:18:09+02:00 rts: retainer: Turn global traversal state into a struct Global state is ugly and hard to test. Since the profiling code isn't quite as performance critical as, say, GC we should prefer better code here. I would like to move the 'flip' bit into the struct too but that's complicated by the fact that the defines which use it directly are also called from ProfHeap where the traversalState is not easily available. Maybe in a future commit. - - - - - 94ecdb4f by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move info.next.parent to stackElement I don't see a point in having this live in 'info', just seems to make the code more complicated. - - - - - f79ac2ef by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Generalise per-stackElement data This essentially ammounts to s/retainer/stackData/, s/c_child_r/data/ and some temporary casting of c_child_r to stackData until refactoring of this module is completed by a subsequent commit. We also introduce a new union 'stackData' which will contain the actual extra data to be stored on the stack. The idea is to make the heap traversal logic of the retainer profiler ready for extraction into it's own module. So talking about "retainers" there doesn't really make sense anymore. Essentially the "retainers" we store in the stack are just data associated with the push()ed closures which we return when pop()ing it. - - - - - f083358b by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Fix comment typo s/keeps/keep/ - - - - - 2f2f6dd5 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: Generalise profiling heap traversal flip bit handling This commit starts renaming some flip bit related functions for the generalised heap traversal code and adds provitions for sharing the per-closure profiling header field currently used exclusively for retainer profiling with other heap traversal profiling modes. - - - - - e40b3c23 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: GC: Remove redundant #include "RetainerProfiler.h" - - - - - b03db9da by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Pull retainer specific code into a callback This essentially turns the heap traversal code into a visitor. You add a bunch of roots to the work-stack and then the callback you give to traverseWorkStack() will be called with every reachable closure at least once. - - - - - 48e816f0 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: simplify pop() control flow Instead of breaking out of the switch-in-while construct using `return` this uses `goto out` which makes it possible to share a lot of the out-variable assignment code in all the cases. I also replaced the nasty `while(true)` business by the real loop condition: `while(*c == NULL)`. All `break` calls inside the switch aready have either a check for NULL or an assignment of `c` to NULL so this should not change any behaviour. Using `goto out` also allowed me to remove another minor wart: In the MVAR_*/WEAK cases the popOff() call used to happen before reading the stackElement. This looked like a use-after-free hazard to me as the stack is allocated in blocks and depletion of a block could mean it getting freed and possibly overwritten by zero or garbage, depending on the block allocator's behaviour. - - - - - b92ed68a by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: Add note reference to SET_PROF_HDR for profiling 'flip' bit - - - - - f3bb7397 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerSet: Remove obsolete fist/second-approach choice In the old code when DEBUG_RETAINER was set, FIRST_APPROACH is implied. However ProfHeap.c now depends on printRetainerSetShort which is only available with SECOND_APPROACH. This is because with FIRST_APPROACH retainerProfile() will free all retainer sets before returning so by the time ProfHeap calls dumpCensus the retainer set pointers are segfaulty. Since all of this debugging code obviously hasn't been compiled in ages anyways I'm taking the liberty of just removing it. Remember guys: Dead code is a liability not an asset :) - - - - - ec1d76e2 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Remove obsolete debug code Commit dbef766ce7 ("Profiling cleanup.") made this debug code obsolete by removing the 'cost' function without a replacement. As best I can tell the retainer profiler used to do some heap census too and this debug code was mainly concerned with that. - - - - - b7e15d17 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Rename heap traversal functions for extraction This gets all remaining functions in-line with the new 'traverse' prefix and module name. - - - - - 64ec45a7 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Reduce DEBUG_RETAINER ifdef noise Keeping track of the maximum stack seems like a good idea in all configurations. The associated ASSERTs only materialize in debug mode but having the statistic is nice. To make the debug code less prone to bitrotting I introduce a function 'debug()' which doesn't actually print by default and is #define'd away only when the standard DEBUG define is off. - - - - - bd78b696 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Cleanup comments and strings for traversal extraction A lot of comments and strings are still talking about old names, fix that. - - - - - cb7220b3 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Remove outdated invariants on traversePushStack These invariants don't seem to make any sense in the current code. The text talks about c_child_r as if it were an StgClosure, for which RSET() would make sense, but it's a retainer aka 'CostCentreStack*'. - - - - - bb92660c by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Use global STATIC_INLINE macro STATIC_INLINE already does what the code wanted here, no need to duplicate the functionality here. - - - - - 2b76cf9e by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move heap traversal declarations to new header - - - - - 44d5cc0d by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Abstract maxStackSize for generic traversal - - - - - fd213d17 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Update obsolete docs for traverseMaybeInitClosureData - - - - - 39f2878c by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move actual 'flip' bit flip to generic traversal code - - - - - f9b4c4f2 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Remove traverse-stack chunk support There's simply no need anymore for this whole business. Instead of individually traversing roots in retainRoot() we just push them all onto the stack and traverse everything in one go. This feature was not really used anyways. There is an `ASSERT(isEmptyWorkStack(ts))` at the top of retainRoot() which means there really can't ever have been any chunks at the toplevel. The only place where this was probably used is in traversePushStack but only way back when we were still using explicit recursion on the C callstack. Since the code was changed to use an explicit traversal-stack these stack-chunks can never escape one call to traversePushStack anymore. See commit 5f1d949ab9 ("Remove explicit recursion in retainer profiling") - - - - - c7def600 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Move mut_list reset to generic traversal code - - - - - 9bf27060 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Make visit callback easier to implement Currently it is necessary for user code to expend at least one extra bit in the closure header just to know whether visit() should return true or false, to indicate if children should be traversed. The generic traversal code already has this information in the visited bit so simply pass it to the visit callback. - - - - - 96adf179 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: retainer: Improve Note [Profiling heap traversal visited bit] - - - - - 187192a6 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerProfile.c: Re-enable and fix warnings Turns out some genius disabled warnings for RetainerProfile.c in the build system. That would have been good to know about five silent type mismatch crashes ago.. :) - - - - - eb29735e by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerProfile.c: Minimize #includes A lot of these includes are presumably leftovers from when the retainer profiler still did it's own heap profiling. - - - - - 383f9089 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: Split heap traversal from retainer profiler This finally moves the newly generalised heap traversal code from the retainer profiler into it's own file. - - - - - 52c5ea71 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: TraverseHeap: Make comment style consistent - - - - - 75355228 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: TraverseHeap: Make pushStackElement argument const - - - - - a8137780 by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: TraverseHeap: Move stackElement.cp back into nextPos union The 'cp' field really is only used when type==posTypeFresh so it's more space efficient to have it in the nextPos union. - - - - - 7f10cc2d by Daniel Gröber at 2019-09-22T15:18:10+02:00 rts: RetainerProfile: Explain retainVisitClosure return values [ci skip] - - - - - 111f2761 by Daniel Gröber at 2019-09-22T15:33:41+02:00 rts: TraverseHeap: Add doc comment for getTraverseStackMaxSize - - - - - 68ddb43c by Ben Gamari at 2019-09-23T00:34:00-04:00 gitlab-ci: Fix URL of Windows cabal-install tarball - - - - - 0e478407 by Takenobu Tani at 2019-09-23T17:51:37-04:00 users-guide: Fix links and formats for GHC 8.10 This commit only fixes links and markdown syntax. [skip ci] - - - - - 74631bbc by Adam Sandberg Eriksson at 2019-09-23T17:52:32-04:00 base: add newtypes for socklen_t and ndfs_t to System.Posix.Types #16568 Metric Increase: haddock.base T4029 - - - - - 4470a144 by Björn Gohla at 2019-09-23T17:53:23-04:00 add Hadrian rule to build user guide as Info book - - - - - dbbea5a8 by Björn Gohla at 2019-09-23T17:53:23-04:00 use the Make builder instead of raw cmd_ - - - - - b0e3b173 by Björn Gohla at 2019-09-23T17:53:23-04:00 detect makeinfo in configure(.ac) - - - - - 9fe4d2df by Björn Gohla at 2019-09-23T17:53:23-04:00 explicit dependence on makeinfo - - - - - b650c2b6 by Björn Gohla at 2019-09-23T17:53:23-04:00 alphabetical ordering - - - - - 27789294 by Björn Gohla at 2019-09-23T17:53:23-04:00 sort-paragraphs in runBuilderWith - - - - - d0c2f3a2 by Artem Pyanykh at 2019-09-23T17:54:04-04:00 [hadrian] Rebuild programs on dynamicGhcPrograms/ghcProfiled change Currently, if you change these ^ flavour parameters, rebuilding is not triggered, since `programContext` doesn't set up a dependency on those values. Exposing these values via an oracle does set the dependency and properly triggers a rebuild of binaries. Several attempts to factor out these actions ended up in cyclic dependency here or there. I'm not absolutely happy with this variant either, but at least it works. ==== Issue repro: In UserSettings.hs: ``` dbgDynamic = defaultFlavour { name = "dbg-dynamic" , dynamicGhcPrograms = pure True, ... } dbgStatic = defaultFlavour { name = "dbg-static" , dynamicGhcPrograms = pure False ... } ``` Then in console: ``` $ hadrian/build.sh -j --flavour=dbg-dynamic ... does the build $ hadrian/build.sh -j --flavour=dbg-static ... does nothing, considers binaries up to date ``` - - - - - 238b58e4 by Kari Pahula at 2019-09-23T17:54:42-04:00 Add -fkeep-going to make compiler continue despite errors (#15424) Add a new optional failure handling for upsweep which continues the compilation on other modules if any of them has errors. - - - - - 146f26cc by Sebastian Graf at 2019-09-24T01:06:40-04:00 Some leftovers from !1732. Comments only [skip ci] - - - - - b5f24fb4 by Takenobu Tani at 2019-09-24T01:07:19-04:00 Hadrian: Add -haddock option for GHCi's :doc command This commit adds -haddock option to Hadrian-based build system. To enable :doc command on GHCi, core libraries must be compiled with -haddock option. Especially, the `-haddock` option is essential for a release build. Assuming current GitLab CI condition (.gitlab-ci.yml), I add -haddock option to the default flavour only. This has already been done for Make-based build system. Please see #16415. - - - - - f97a7aac by Sebastian Graf at 2019-09-24T01:07:57-04:00 Fix some duplication in the parser D3673 experienced reduce/reduce conflicts when trying to use opt_instance for associated data families. That was probably because the author tried to use it for Haskell98-syntax without also applying it to GADT-syntax, which actually leads to a reduce/reduce conflict. Consider the following state: ``` data . T = T data . T where T :: T ``` The parser must decide at this point whether or not to reduce an empty `opt_instance`. But doing so would also commit to either Haskell98 or GADT syntax! Good thing we also accept an optional "instance" for GADT syntax, so the `opt_instance` is there in both productions and there's no reduce/reduce conflict anymore. Also no need to inline `opt_instance`, how it used to be. - - - - - b23f01fd by Ben Gamari at 2019-09-24T08:49:43-04:00 base: Add link to "A reflection on types" Fixes #17181. - - - - - 4bbe0dba by Ben Gamari at 2019-09-24T08:50:20-04:00 gitlab-ci: Bump ci-images This bumps the CI Docker images to ghc/ci-images at 990c5217d1d0e03aea415f951afbc3b1a89240c6. - - - - - 6bca867c by Ben Gamari at 2019-09-24T08:50:59-04:00 hadrian: Update source-repository - - - - - b2d47536 by Ben Gamari at 2019-09-24T08:51:45-04:00 testsuite: Mark threadstatus-9333 as fragile in profthreaded Due to #16555. - - - - - ed520678 by Andreas Klebinger at 2019-09-24T21:08:42-04:00 Fix bounds check in ocResolve_PEi386 for relocation values. The old test was wrong at least for gcc and the value -2287728808L. It also relied on implementation defined behaviour (right shift on a negative value), which might or might not be ok. Either way it's now a simple comparison which will always work. - - - - - 218c5dbf by Matthew Pickering at 2019-09-24T21:09:23-04:00 Add ghcide configuration files This commit adds three new files 1. A hie.yaml file to the project root which specifies to IDEs how to set up the correct environment for loading GHC. This currently specifies to call the `./hadrian/hie-bios` script. 2. A `hie.yaml` file for the hadrian subcomponent, which uses the `cabal` cradle type. 2. The `./hadrian/hie-bios` script which supplies the correct arguments for an IDE to start a session. With these two files it is possible to run ``` ghcide compiler/ ``` and successfully load all the modules for use in the IDE. or ``` ghcide --cwd hadrian/ src/ ``` to test loading all of Hadrian's modules. Closes #17194 - - - - - 2970dc7a by Kari Pahula at 2019-09-25T13:52:48-04:00 Add -Wderiving-defaults (#15839) Enabling both DeriveAnyClass and GeneralizedNewtypeDeriving can cause a warning when no explicit deriving strategy is in use. This change adds an enable/suppress flag for it. - - - - - 4540bbe2 by John Ericson at 2019-09-25T13:53:42-04:00 includes/CodeGen.Platform.hs don't include ghcautoconf.h It doesn't need it, and it shouldn't need it or else multi-target will break. - - - - - ebc65025 by Sebastian Graf at 2019-09-25T13:54:22-04:00 PmCheck: Only ever check constantly many models against a single pattern Introduces a new flag `-fmax-pmcheck-deltas` to achieve that. Deprecates the old `-fmax-pmcheck-iter` mechanism in favor of this new flag. >From the user's guide: Pattern match checking can be exponential in some cases. This limit makes sure we scale polynomially in the number of patterns, by forgetting refined information gained from a partially successful match. For example, when matching `x` against `Just 4`, we split each incoming matching model into two sub-models: One where `x` is not `Nothing` and one where `x` is `Just y` but `y` is not `4`. When the number of incoming models exceeds the limit, we continue checking the next clause with the original, unrefined model. This also retires the incredibly hard to understand "maximum number of refinements" mechanism, because the current mechanism is more general and should catch the same exponential cases like PrelRules at the same time. ------------------------- Metric Decrease: T11822 ------------------------- - - - - - d90d0bad by Ben Gamari at 2019-09-25T13:55:09-04:00 base: Move Ix typeclass to GHC.Ix The `Ix` class seems rather orthogonal to its original home in `GHC.Arr`. - - - - - 795986aa by Ryan Scott at 2019-09-25T13:56:07-04:00 Remove unneeded CPP now that GHC 8.6 is the minimum The minimum required GHC version for bootstrapping is 8.6, so we can get rid of some unneeded `#if `__GLASGOW_HASKELL__` CPP guards, as well as one `MIN_VERSION_ghc_prim(0,5,3)` guard (since GHC 8.6 bundles `ghc-prim-0.5.3`). - - - - - 0b5eede9 by Vladislav Zavialov at 2019-09-25T21:06:04+03:00 Standalone kind signatures (#16794) Implements GHC Proposal #54: .../ghc-proposals/blob/master/proposals/0054-kind-signatures.rst With this patch, a type constructor can now be given an explicit standalone kind signature: {-# LANGUAGE StandaloneKindSignatures #-} type Functor :: (Type -> Type) -> Constraint class Functor f where fmap :: (a -> b) -> f a -> f b This is a replacement for CUSKs (complete user-specified kind signatures), which are now scheduled for deprecation. User-facing changes ------------------- * A new extension flag has been added, -XStandaloneKindSignatures, which implies -XNoCUSKs. * There is a new syntactic construct, a standalone kind signature: type <name> :: <kind> Declarations of data types, classes, data families, type families, and type synonyms may be accompanied by a standalone kind signature. * A standalone kind signature enables polymorphic recursion in types, just like a function type signature enables polymorphic recursion in terms. This obviates the need for CUSKs. * TemplateHaskell AST has been extended with 'KiSigD' to represent standalone kind signatures. * GHCi :info command now prints the kind signature of type constructors: ghci> :info Functor type Functor :: (Type -> Type) -> Constraint ... Limitations ----------- * 'forall'-bound type variables of a standalone kind signature do not scope over the declaration body, even if the -XScopedTypeVariables is enabled. See #16635 and #16734. * Wildcards are not allowed in standalone kind signatures, as partial signatures do not allow for polymorphic recursion. * Associated types may not be given an explicit standalone kind signature. Instead, they are assumed to have a CUSK if the parent class has a standalone kind signature and regardless of the -XCUSKs flag. * Standalone kind signatures do not support multiple names at the moment: type T1, T2 :: Type -> Type -- rejected type T1 = Maybe type T2 = Either String See #16754. * Creative use of equality constraints in standalone kind signatures may lead to GHC panics: type C :: forall (a :: Type) -> a ~ Int => Constraint class C a where f :: C a => a -> Int See #16758. Implementation notes -------------------- * The heart of this patch is the 'kcDeclHeader' function, which is used to kind-check a declaration header against its standalone kind signature. It does so in two rounds: 1. check user-written binders 2. instantiate invisible binders a la 'checkExpectedKind' * 'kcTyClGroup' now partitions declarations into declarations with a standalone kind signature or a CUSK (kinded_decls) and declarations without either (kindless_decls): * 'kinded_decls' are kind-checked with 'checkInitialKinds' * 'kindless_decls' are kind-checked with 'getInitialKinds' * DerivInfo has been extended with a new field: di_scoped_tvs :: ![(Name,TyVar)] These variables must be added to the context in case the deriving clause references tcTyConScopedTyVars. See #16731. - - - - - 4f81fab0 by Ryan Scott at 2019-09-26T14:04:38-04:00 Make -fbyte-code prevent unboxed tuples/sums from implying object code (#16876) This resolves #16876 by making the explicit use of `-fbyte-code` prevent code that enables `UnboxedTuples` or `UnboxedSums` from automatically compiling to object code. This allows for a nice middle ground where most code that enables `UnboxedTuples`/-`Sums` will still benefit from automatically enabling `-fobject-code`, but allows power users who wish to avoid this behavior in certain corner cases (such as `lens`, whose use case is documented in #16876) to do so. Along the way, I did a little cleanup of the relevant code and documentation: * `enableCodeGenForUnboxedTuples` was only checking for the presence of `UnboxedTuples`, but `UnboxedSums` has the same complications. I fixed this and renamed the function to `enableCodeGenForUnboxedTuplesOrSums`. * I amended the users' guide with a discussion of these issues. - - - - - 289fc8da by Sebastian Graf at 2019-09-27T22:10:17-04:00 PmCheck: Elaborate what 'model' means in the user guide [skip ci] - - - - - 9c02a793 by Ron Mordechai at 2019-09-27T22:11:06-04:00 Allow users to disable Unicode with an env var Unicode renders funny on my terminal and I like to avoid it where possible. Most applications which print out non-ascii characters allow users to disable such prints with an environment variable (e.g. Homebrew). This diff disables Unicode usage when the environment variable `GHC_NO_UNICODE` is set. To test, set the env var and compile a bad program. Note that GHC does not print Unicode bullets but instead prints out asterisks: ``` $ GHC_NO_UNICODE= _build/stage1/bin/ghc ../Temp.hs [1 of 1] Compiling Temp ( ../Temp.hs, ../Temp.o ) ../Temp.hs:4:23: error: * Couldn't match type `Bool' with `a -> Bool' Expected type: Bool -> a -> Bool Actual type: Bool -> Bool * In the first argument of `foldl', namely `(&& (flip $ elem u))' In the expression: foldl (&& (flip $ elem u)) True v In an equation for `isPermut': isPermut u v = foldl (&& (flip $ elem u)) True v * Relevant bindings include v :: [a] (bound at ../Temp.hs:4:12) u :: [a] (bound at ../Temp.hs:4:10) isPermut :: [a] -> [a] -> Bool (bound at ../Temp.hs:4:1) | 4 | isPermut u v = foldl (&& (flip $ elem u)) True v | ^^^^^^^^^^^^^^^^^^ ``` (Broken code taken from Stack Overflow) - - - - - 144abba3 by Ben Gamari at 2019-09-27T22:11:53-04:00 configure: Don't depend upon alex in source dist build This fixes #16860 by verifying that the generated sources don't already exist before asserting that the `alex` executable was found. This replicates the logic already used for `happy` in the case of `alex`. - - - - - c6fb913c by John Ericson at 2019-09-27T22:12:35-04:00 Just get RTS libs from its package conf `rts.conf` already contains this exact information in its `extra-libraries` stanza. - - - - - f07862b4 by Ben Gamari at 2019-09-27T22:13:16-04:00 ghc-prim: Fix documentation of Type As pointed out in #17243, `Type` is not the only kind having values. - - - - - 0201d0bf by chris-martin at 2019-09-27T22:14:00-04:00 Clarify the purpose and status of the GHC.TypeLits module - - - - - 444e554f by chris-martin at 2019-09-27T22:14:00-04:00 Expand description of DataKinds to mention data constructors, and include mention of TypeError - - - - - 1582dafa by Sebastian Graf at 2019-09-27T22:14:44-04:00 PmCheck: Look at precendence to give type signatures to some wildcards Basically do what we currently only do for -XEmptyCase in other cases where adding the type signature won't distract from pattern matches in other positions. We use the precedence to guide us, equating "need to parenthesise" with "too much noise". - - - - - ad0c4390 by Shayne Fletcher at 2019-09-27T22:15:27-04:00 Add test for expected dependencies of 'Parser' - - - - - 0b1fa64d by Ben Gamari at 2019-09-27T22:16:04-04:00 testsuite: Mark cgrun071 as broken on i386 As described in #17247. - - - - - 24620182 by Daniel Gröber at 2019-09-27T22:17:04-04:00 Raise minimum GHC version to 8.6 commit 795986aaf33e ("Remove unneeded CPP now that GHC 8.6 is the minimum") broke the 8.4 build. - - - - - e0bbb961 by Ben Gamari at 2019-09-27T22:17:44-04:00 testsuite: Mark compact_gc as fragile in the ghci way As noted in #17253. - - - - - bb984ac6 by Ben Gamari at 2019-09-27T22:18:42-04:00 testsuite: Mark hs_try_putmvar003 as fragile in threaded1 Due to #16361. Note that I'm leaving out threaded2 since it's not clear whether the single crash in that way was due to other causes. - - - - - ad2a1f99 by Ben Gamari at 2019-09-27T22:19:26-04:00 testsuite: Mark T3389 as broken in profiled ways on i386 As noted in #17256. - - - - - 6f9fa0be by Ben Gamari at 2019-09-27T22:20:04-04:00 testsuite: Mark TH tests as fragile in LLVM built external-interpreter Due to #16087. This drops the previous explicit list of broken tests and rather encompasses the entire set of tests since they all appear to be broken. - - - - - c5d888d4 by Sebastian Graf at 2019-09-28T17:11:41-04:00 PmCheck: No ConLike instantiation in pmcheck `pmcheck` used to call `refineToAltCon` which would refine the knowledge we had about a variable by equating it to a `ConLike` application. Since we weren't particularly smart about this in the Check module, we simply freshened the constructors existential and term binders utimately through a call to `mkOneConFull`. But that instantiation is unnecessary for when we match against a concrete pattern! The pattern will already have fresh binders and field types. So we don't call `refineToAltCon` from `Check` anymore. Subsequently, we can simplify a couple of call sites and functions in `PmOracle`. Also implementing `computeCovered` becomes viable and we don't have to live with the hack that was `addVarPatVecCt` anymore. A side-effect of not indirectly calling `mkOneConFull` anymore is that we don't generate the proper strict argument field constraints anymore. Instead we now desugar ConPatOuts as if they had bangs on their strict fields. This implies that `PmVar` now carries a `HsImplBang` that we need to respect by a (somewhat ephemeral) non-void check. We fix #17234 in doing so. - - - - - ce64b397 by Sebastian Graf at 2019-09-28T17:12:26-04:00 `exprOkForSpeculation` for Note [IO hack in the demand analyser] In #14998 I realised that the notion of speculative execution *exactly matches* eager evaluation of expressions in a case alternative where the scrutinee is an IO action. Normally we have to `deferIO` any result from that single case alternative to prevent this speculative execution, so we had a special case in place in the demand analyser that would check if the scrutinee was a prim-op, in which case we assumed that it would be ok to do the eager evaluation. Now we just check if the scrutinee is `exprOkForSpeculation`, corresponding to the notion that we want to push evaluation of the scrutinee *after* eagerly evaluating stuff from the case alternative. This fixes #14988, because it resolves the last open Item 4 there. - - - - - f3cb8c7c by Ömer Sinan Ağacan at 2019-09-30T22:39:53-04:00 Refactor iface file generation: This commit refactors interface file generation to allow information from the later passed (NCG, STG) to be stored in interface files. We achieve this by splitting interface file generation into two parts: * Partial interfaces, built based on the result of the core pipeline * A fully instantiated interface, which also contains the final fingerprints and can optionally contain information produced by the backend. This change is required by !1304 and !1530. -dynamic-too handling is refactored too: previously when generating code we'd branch on -dynamic-too *before* code generation, but now we do it after. (Original code written by @AndreasK in !1530) Performance ~~~~~~~~~~~ Before this patch interface files where created and immediately flushed to disk which made space leaks impossible. With this change we instead use NFData to force all iface related data structures to avoid space leaks. In the process of refactoring it was discovered that the code in the ToIface Module allocated a lot of thunks which were immediately forced when writing/forcing the interface file. So we made this module more strict to avoid creating many of those thunks. Bottom line is that allocations go down by about ~0.1% compared to master. Residency is not meaningfully different after this patch. Runtime was not benchmarked. Co-Authored-By: Andreas Klebinger <klebinger.andreas at gmx.at> Co-Authored-By: Ömer Sinan Ağacan <omer at well-typed.com> - - - - - 6a1700aa by Simon Peyton Jones at 2019-09-30T22:40:30-04:00 Fix arguments for unbound binders in RULE application We were failing to correctly implement Note [Unbound RULE binders] in Rules.hs. In particular, when cooking up a fake Refl, were were failing to apply the substitition. This patch fixes that problem, and simultaneously tidies up the impedence mis-match between RuleSubst and TCvSubst. Thanks to Sebastian! - - - - - 97811ef5 by Takenobu Tani at 2019-09-30T22:41:35-04:00 Add help message for GHCi :instances command This commit updates GHCi's help message for GHC 8.10. - - - - - 6f8550a3 by Sebastian Graf at 2019-09-30T22:42:14-04:00 Move pattern match checker modules to GHC.HsToCore.PmCheck - - - - - b36dd49b by Takenobu Tani at 2019-09-30T22:42:53-04:00 testsuite: Add minimal test for :doc command Currently, there are no testcases for GHCi `:doc` command. Perhaps because it was experimental. And it could be changed in the future. But `:doc` command is already useful, so I add a minimal regression test to keep current behavior. See also 85309a3cda for implementation of `:doc` command. - - - - - bdba6ac2 by Vladislav Zavialov at 2019-09-30T22:43:31-04:00 Do not rely on CUSKs in 'base' Use standalone kind signatures instead of complete user-specified kinds in Data.Type.Equality and Data.Typeable - - - - - dbdf6a3d by Ben Gamari at 2019-09-30T22:44:07-04:00 testsuite: Mark T3389 as broken in hpc way on i386 See #17256. - - - - - 822481d5 by Ben Gamari at 2019-09-30T22:44:44-04:00 Bump process submodule Marks process003 as fragile, as noted in #17245. - - - - - 6548b7b0 by Sebastian Graf at 2019-10-01T09:22:10+00:00 Add a bunch of testcases for the pattern match checker Adds regression tests for tickets #17207, #17208, #17215, #17216, #17218, #17219, #17248 - - - - - 58013220 by Sebastian Graf at 2019-10-01T09:22:18+00:00 Add testcases inspired by Luke Maranget's pattern match series In his paper "Warnings for Pattern Matching", Luke Maranget describes three series in his appendix for which GHC's pattern match checker scaled very badly. We mostly avoid this now with !1752. This commit adds regression tests for each of the series. Fixes #17264. - - - - - 9c002177 by Ryan Scott at 2019-10-01T16:24:12-04:00 Refactor some cruft in TcDeriv * `mk_eqn_stock`, `mk_eqn_anyclass`, and `mk_eqn_no_mechanism` all took a continuation of type `DerivSpecMechanism -> DerivM EarlyDerivSpec` to represent its primary control flow. However, in practice this continuation was always instantiated with the `mk_originative_eqn` function, so there's not much point in making this be a continuation in the first place. This patch removes these continuations in favor of invoking `mk_originative_eqn` directly, which is simpler. * There were several parts of `TcDeriv` that took different code paths if compiling an `.hs-boot` file. But this is silly, because ever since 101a8c770b9d3abd57ff289bffea3d838cf25c80 we simply error eagerly whenever attempting to derive any instances in an `.hs-boot` file. This patch removes all of the unnecessary `.hs-boot` code paths, leaving only one (which errors out). * Remove various error continuation arguments from `mk_eqn_stock` and related functions. - - - - - 9a27a063 by David Eichmann at 2019-10-01T16:55:33-04:00 Hadrian: Libffi rule now `produces` dynamic library files. - - - - - 0956c194 by David Eichmann at 2019-10-01T16:55:33-04:00 Hadrian: do not cache GHC configure rule - - - - - 8924224e by Ömer Sinan Ağacan at 2019-10-01T16:55:37-04:00 Make small INLINE functions behave properly Simon writes: Currently we check for a type arg rather than isTyCoArg. This in turn makes INLINE things look bigger than they should be, and stops them being inlined into boring contexts when they perfectly well could be. E.g. f x = g <refl> x {-# INLINE g #-} ... (map (f x) xs) ... The context is boring, so don't inline unconditionally. But f's RHS is no bigger than its call, provided you realise that the coercion argument is ultimately cost-free. This happens in practice for $WHRefl. It's not a big deal: at most it means we have an extra function call overhead. But it's untidy, and actually worse than what happens without an INLINE pragma. Fixes #17182 This makes 0.0% change in nofib binary sizes. - - - - - 53b0c6e0 by Gabor Greif at 2019-10-03T08:15:50-04:00 Typo in comment [ci skip] - - - - - 60229e9e by Ryan Scott at 2019-10-03T12:17:10-04:00 Merge TcTypeableValidity into TcTypeable, document treatment of casts This patch: * Implements a refactoring (suggested in https://gitlab.haskell.org/ghc/ghc/merge_requests/1199#note_207345) that moves all functions from `TcTypeableValidity` back to `TcTypeable`, as the former module doesn't really need to live on its own. * Adds `Note [Typeable instances for casted types]` to `TcTypeable` explaining why the `Typeable` solver currently does not support types containing casts. Resolves #16835. - - - - - 3b9d4907 by Richard Eisenberg at 2019-10-03T12:17:13-04:00 Note [Don't flatten tuples from HsSyn] in MkCore Previously, we would sometimes flatten 1-tuples and sometimes not. This didn't cause damage because there is no way to generate HsSyn with 1-tuples. But, with the upcoming fix to #16881, there will be. Without this patch, obscure lint errors would have resulted. No test case, as there is not yet a way to tickle this. - - - - - 8a254d6b by Ömer Sinan Ağacan at 2019-10-03T12:17:19-04:00 Fix new compact block allocation in allocateForCompact allocateForCompact() is called when nursery of a compact region is full, to add new blocks to the compact. New blocks added to an existing region needs a StgCompactNFDataBlock header, not a StgCompactNFData. This fixes allocateForCompact() so that it now correctly allocates space for StgCompactNFDataBlock instead of StgCompactNFData as before. Fixes #17044. A regression test T17044 added. - - - - - 3c7b172b by James Brock at 2019-10-03T12:17:24-04:00 docs String, hyperlink to Data.List Add a reference to the documentation for Data.List in the description for String. On the generated Haddock for Data.String, http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-String.html there is curently no hyperlink to Data.List, which is where a reader will find most of the useful functions which can operate on Strings. I imagine this has confused beginners who came to this page looking for String operations. - - - - - 67bf734c by John Ericson at 2019-10-03T12:17:28-04:00 Add `module {-# SOURCE #-} Foo` syntax for hs-boot in bkp This is a good convenience for testing. - - - - - 6655ec73 by Richard Eisenberg at 2019-10-03T12:17:30-04:00 Improve documentation around empty tuples/lists This patch also changes the way we handle empty lists, simplifying them somewhat. See Note [Empty lists]. Previously, we had to special-case empty lists in the type-checker. Now no more! Finally, this patch improves some documentation around the ir_inst field used in the type-checker. This breaks a test case, but I really think the problem is #17251, not really related to this patch. Test case: typecheck/should_compile/T13680 - - - - - 9a4ff210 by John Ericson at 2019-10-03T12:17:31-04:00 Make Haddock submodule remote point to gitlab mirror This makes it match the others - - - - - cb364bc2 by Ben Gamari at 2019-10-03T12:17:32-04:00 testsuite: Mark print037 as fragile, not broken See #16205. - - - - - 259f4dff by Ben Gamari at 2019-10-03T12:17:32-04:00 Exclude rts.cabal from source distributions This modifies both the Hadrian and make build systems to avoid included the rts.cabal generated by autoconf in the source distribution. Fixes #17265. - - - - - e4c93896 by Ben Gamari at 2019-10-03T12:17:32-04:00 DynFlags: Only warn when split-sections is ignored Previously we would throw an error which seems a bit harsh. As reported in #17283. - - - - - ee6324ad by Tobias Guggenmos at 2019-10-03T12:17:33-04:00 Improve documentation for runtime debugging flags - - - - - 47386fe8 by Tobias Guggenmos at 2019-10-03T12:17:33-04:00 Add new debug flag -DZ Zeros heap memory after gc freed it. - - - - - d0924b15 by Stefan Schulze Frielinghaus at 2019-10-03T12:17:34-04:00 Extend argument of createIOThread to word size Function createIOThread expects its second argument to be of size word. The natural size of the second parameter is 32bits. Thus for some 64bit architectures, where a write of the lower half of a register does not clear the upper half, the value must be zero extended. - - - - - 1357d023 by Ben Gamari at 2019-10-03T12:17:34-04:00 rules/haddock: Ensure that RTS stats directory exists It may not exist if the source tarball was extracted yet not the testsuite tarball. - - - - - ec93d2a9 by Fumiaki Kinoshita at 2019-10-04T21:43:49-04:00 Add Monad instances to `(,,) a b` and `(,,,) a b c` - - - - - 05419e55 by John Ericson at 2019-10-04T21:44:29-04:00 Per stage headers, ghc_boot_platform.h -> stage 0 ghcplatform.h The generated headers are now generated per stage, which means we can skip hacks like `ghc_boot_platform.h` and just have that be the stage 0 header as proper. In general, stages are to be embraced: freely generate everything in each stage but then just build what you depend on, and everything is symmetrical and efficient. Trying to avoid stages because bootstrapping is a mind bender just creates tons of bespoke mini-mind-benders that add up to something far crazier. Hadrian was pretty close to this "stage-major" approach already, and so was fairly easy to fix. Make needed more work, however: it did know about stages so at least there was a scaffold, but few packages except for the compiler cared, and the compiler used its own counting system. That said, make and Hadrian now work more similarly, which is good for the transition to Hadrian. The merits of embracing stage aside, the change may be worthy for easing that transition alone. - - - - - 75a5dd8e by John Ericson at 2019-10-04T21:44:29-04:00 Remove {Build,Host}Platform_NAME from header They are only used in a file we construct directly, so just skip CPP. - - - - - b538476b by Daroc Alden at 2019-10-04T21:45:09-04:00 Deprecate -fwarn-hi-shadowing, because it was never implemented and is not used. This fixes #10913. - - - - - dd8f76b2 by John Ericson at 2019-10-04T21:45:48-04:00 Factor out a smaller part of Platform for host fallback - - - - - d15b44d6 by John Ericson at 2019-10-04T21:45:49-04:00 Pull out the settings file parsing code into it's own module. This has two benefits: 1. One less hunk of code dependent on DynFlags 2. Add a little bit of error granularity to distrinugish between missing data and bad data. This could someday be shared with ghc-pkg which aims to work even with a missing file. I also am about to to make --supported-extensions use this too. - - - - - eb892b28 by John Ericson at 2019-10-04T21:45:49-04:00 Add tryFindTopDir to look for the top dir without blowing up if it is not found. - - - - - 0dded5ec by John Ericson at 2019-10-04T21:45:49-04:00 Always enable the external interpreter You can always just not use or even build `iserv`. I don't think the maintenance cost of the CPP is worth...I can't even tell what the benefit is. - - - - - 0d31ccdd by Artem Pyanykh at 2019-10-04T21:46:28-04:00 [linker, macho] Don't map/allocate zero size sections and segments Zero size sections are common even during regular build on MacOS. For instance: ``` $ ar -xv libHSghc-prim-0.6.1.a longlong.o $ otool -l longlong.o longlong.o: Mach header magic cputype cpusubtype caps filetype ncmds sizeofcmds flags 0xfeedfacf 16777223 3 0x00 1 2 176 0x00002000 Load command 0 cmd LC_SEGMENT_64 cmdsize 152 segname vmaddr 0x0000000000000000 vmsize 0x0000000000000000 <-- segment size = 0 fileoff 208 filesize 0 maxprot 0x00000007 initprot 0x00000007 nsects 1 flags 0x0 Section sectname __text segname __TEXT addr 0x0000000000000000 size 0x0000000000000000 <-- section size = 0 offset 208 align 2^0 (1) reloff 0 nreloc 0 flags 0x80000000 reserved1 0 reserved2 0 cmd LC_BUILD_VERSION cmdsize 24 platform macos sdk 10.14 minos 10.14 ntools 0 ``` The issue of `mmap`ing 0 bytes was resolved in !1050, but the problem remained. These 0 size segments and sections were still allocated in object code, which lead to failed `ASSERT(size > 0)` in `addProddableBlock` further down the road. With this change zero size segments **and** sections are not mapped/allocated at all. Test plan: 1. Build statically linked GHC. 2. Run `ghc --interactive`. Observe that REPL loads successfully (which was not the case before). 3. Load several more compiled hs files into repl. No failures. - - - - - 93f02b62 by Roland Senn at 2019-10-04T21:47:07-04:00 New fix for #11647. Avoid side effects like #17171 If a main module doesn't contain a header, we omit the check whether the main module is exported. With this patch GHC, GHCi and runghc use the same code. - - - - - 8039b625 by Matthew Bauer at 2019-10-04T21:47:47-04:00 Add musl systems to llvm-targets This was done in Nixpkgs, but never upstreamed. Musl is pretty much the same as gnu, but with a different libc. I’ve used the same values for everything. - - - - - ee8118ca by John Ericson at 2019-10-05T00:11:58-04:00 Clean up `#include`s in the compiler - Remove unneeded ones - Use <..> for inter-package. Besides general clean up, helps distinguish between the RTS we link against vs the RTS we compile for. - - - - - 241921a0 by Ben Gamari at 2019-10-05T19:18:40-04:00 rts: Fix CNF dirtying logic Previously due to a silly implementation bug CNFs would never have their dirty flag set, resulting in their being added again and again to the `mut_list`. Fix this. Fixes #17297. - - - - - 825c108b by Ryan Scott at 2019-10-07T12:00:59-04:00 Only flatten up to type family arity in coreFlattenTyFamApp (#16995) Among other uses, `coreFlattenTyFamApp` is used by Core Lint as a part of its check to ensure that each type family axiom reduces according to the way it is defined in the source code. Unfortunately, the logic that `coreFlattenTyFamApp` uses to flatten type family applications disagreed with the logic in `TcFlatten`, which caused it to spuriously complain this program: ```hs type family Param :: Type -> Type type family LookupParam (a :: Type) :: Type where LookupParam (f Char) = Bool LookupParam x = Int foo :: LookupParam (Param ()) foo = 42 ``` This is because `coreFlattenTyFamApp` tries to flatten the `Param ()` in `LookupParam (Param ())` to `alpha` (where `alpha` is a flattening skolem), and GHC is unable to conclude that `alpha` is apart from `f Char`. This patch spruces up `coreFlattenTyFamApp` so that it instead flattens `Param ()` to `alpha ()`, which GHC _can_ know for sure is apart from `f Char`. See `Note [Flatten], wrinkle 3` in `FamInstEnv`. - - - - - b2577081 by Ben Gamari at 2019-10-07T12:01:46-04:00 Refactor, document, and optimize LLVM configuration loading As described in the new Note [LLVM Configuration] in SysTools, we now load llvm-targets and llvm-passes lazily to avoid the overhead of doing so when -fllvm isn't used (also known as "the common case"). Noticed in #17003. Metric Decrease: T12234 T12150 - - - - - 93c71ae6 by Ben Gamari at 2019-10-07T12:02:23-04:00 configure: Determine library versions of template-haskell, et al. These are needed by the user guide documentation. Fixes #17260. - - - - - b7890611 by Andrey Mokhov at 2019-10-07T12:03:13-04:00 Hadrian: Stop using in-tree Cabal - - - - - 0ceb98f6 by Andrey Mokhov at 2019-10-07T12:03:13-04:00 Switch to cabal-version=3.0 in ghc-heap.cabal - - - - - e3418e96 by Andrey Mokhov at 2019-10-07T12:03:13-04:00 Switch to cabal-version=3.0 in base.cabal and rts.cabal - - - - - 805653f6 by John Ericson at 2019-10-07T12:04:19-04:00 Get rid of wildcard patterns in prim Cmm emitting code This way, we can be sure we don't miss a case. - - - - - ab945819 by Ryan Scott at 2019-10-07T12:05:09-04:00 Refactor some cruft in TcGenGenerics * `foldBal` contains needless partiality that can easily be avoided. * `mkProd_E` and `mkProd_P` both contain unique supply arguments that are completely unused, which can be removed. - - - - - d0edba3a by John Ericson at 2019-10-07T12:05:47-04:00 Remove CONFIGURE_ARGS from configure.ac It looks like it's been unused since at least 34cc75e1a62638f2833815746ebce0a9114dc26b. - - - - - 9a6bfb0a by John Ericson at 2019-10-07T12:06:26-04:00 Keep OSTYPE local to configure.ac Unused outside it since b6be81b841e34ca45b3549c4c79e886a8761e59a. - - - - - 4df39fd0 by John Ericson at 2019-10-07T12:07:08-04:00 Get rid of GHC_PACKAGE_DB_FLAG We no longer support booting from older GHC since 527bcc41630918977c73584d99125ff164400695. - - - - - 31a29a7a by John Ericson at 2019-10-07T12:07:46-04:00 Remove GhcLibsWithUnix d679ca43e7477284d733b94ff542be5363be3353 meant to remove it but did not finish the job. - - - - - 77ca39e3 by Ben Gamari at 2019-10-08T05:11:03-04:00 gitlab-ci: Add missing TEST_ENV variables This should fix #16985. - - - - - 9a2798e1 by Ben Gamari at 2019-10-08T05:11:03-04:00 hadrian: Add `validate` and `slow validate` flavours - - - - - ab311696 by Ben Gamari at 2019-10-08T05:11:03-04:00 validate: Use Hadrian's validate flavour - - - - - 98179a77 by Ben Gamari at 2019-10-08T05:11:03-04:00 gitlab-ci: Use validate flavour in hadrian builds - - - - - 8af9eba8 by Ben Gamari at 2019-10-08T05:11:40-04:00 base: Document the fact that Typeable is automatically "derived" This fixes #17060. - - - - - 397c6ed5 by Sebastian Graf at 2019-10-08T05:12:15-04:00 PmCheck: Identify some semantically equivalent expressions By introducing a `CoreMap Id` to the term oracle, we can represent syntactically equivalent expressions by the same `Id`. Combine that with `CoreOpt.simpleCoreExpr` and it might even catch non-trivial semantic equalities. Unfortunately due to scoping issues, this will not solve #17208 for view patterns yet. - - - - - 8a2e8408 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Refer to language extension flags via :extension: Previously several were referred to via :ghc-flag:`-X...`. - - - - - 7cd54538 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Make reverse flags addressable via :ghc-flag: Previously one could not easily link to the :reverse: flag of a ghc-flag. - - - - - e9813afc by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Document -XHaskell98 and -XHaskell2010 - - - - - eaeb28a1 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Fix various warnings - - - - - 180cf177 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Document NondecreasingIndentation - - - - - 0a26f9e8 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Document -fworker-wrapper - - - - - ca4791db by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Rework pragma key generation Previously we had a hack to handle the case of multi-token SPECIALISE pragmas. Now we use a slightly more general rule of using a prefix of tokens containing only alphabetical characters. - - - - - 98c09422 by Ben Gamari at 2019-10-08T05:12:58-04:00 users-guide: Run sphinx in nit-picky mode This ensure that it blurts an error on missing references. - - - - - a95f7185 by Ben Gamari at 2019-10-08T05:12:58-04:00 doc: Write out documented flag list - - - - - 9402608e by Ben Gamari at 2019-10-08T05:12:58-04:00 gitlab-ci: Check coverage of GHC flags in users guide This ensures that all GHC flags are documented during the documentation build. Fixes #17315. - - - - - 9ac3bcbb by Andrew Martin at 2019-10-08T13:24:52-04:00 Document the UnliftedFFITypes extension. - - - - - 77f3ba23 by Andrew Martin at 2019-10-08T13:24:52-04:00 Rephrase a bunch of things in the unlifted ffi types documentation. Add a section on pinned byte arrays. - - - - - a70db7bf by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] link to foreign cmm call - - - - - 0d413259 by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] make the table better - - - - - 0c7a5bcd by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] can not -> may not - - - - - 6a5c249d by Andrew Martin at 2019-10-08T13:24:52-04:00 [skip ci] clarify what unsound means - - - - - bf02c264 by Ryan Scott at 2019-10-08T13:25:37-04:00 Mark newtype constructors as used in the Coercible solver (#10347) Currently, newtype constructors are not marked as used when they are accessed under the hood by uses of `coerce`, as described in #10347. This fixes #10347 by co-opting the `tcg_keep` field of `TcGblEnv` to track uses of newtype constructors in the `Coercible` solver. See `Note [Tracking unused binding and imports]` in `TcRnTypes`. Since #10347 is fixed, I was able to simplify the code in `TcDeriv` slightly, as the hack described in `Note [Newtype deriving and unused constructors]` is no longer necessary. - - - - - 9612e91c by Richard Eisenberg at 2019-10-08T13:26:20-04:00 Solve constraints from top-level groups sooner Previously, all constraints from all top-level groups (as separated by top-level splices) were lumped together and solved at the end. This could leak metavariables to TH, though, and that's bad. This patch solves each group's constraints before running the next group's splice. Naturally, we now report fewer errors in some cases. One nice benefit is that this also fixes #11680, but in a much simpler way than the original fix for that ticket. Admittedly, the error messages degrade just a bit from the fix from #11680 (previously, we informed users about variables that will be brought into scope below a top-level splice, and now we just report an out-of-scope error), but the amount of complexity required throughout GHC to get that error was just not worth it. This patch thus reverts much of f93c9517a2c6e158e4a5c5bc7a3d3f88cb4ed119. Fixes #16980 Test cases: th/T16980{,a} - - - - - c2d4011c by Vladislav Zavialov at 2019-10-08T13:27:12-04:00 Bump array and haddock submodules - - - - - f691f0c2 by Sebastian Graf at 2019-10-08T13:27:49-04:00 PmCheck: Look up parent data family TyCon when populating `PossibleMatches` The vanilla COMPLETE set is attached to the representation TyCon of a data family instance, whereas the user-defined COMPLETE sets are attached to the parent data family TyCon itself. Previously, we weren't trying particularly hard to get back to the representation TyCon to the parent data family TyCon, resulting in bugs like #17207. Now we should do much better. Fixes the original issue in #17207, but I found another related bug that isn't so easy to fix. - - - - - 0c0a15a8 by Ben Gamari at 2019-10-09T16:21:14-04:00 Rename STAGE macro to GHC_STAGE To avoid polluting the macro namespace - - - - - 63a5371d by Ben Gamari at 2019-10-09T16:21:14-04:00 Relayout generated header body - - - - - 817c1a94 by Ben Gamari at 2019-10-09T16:21:14-04:00 Define GHC_STAGE in headers instead of command-line - - - - - 5f2c49d8 by Ben Gamari at 2019-10-09T16:21:14-04:00 Remove GHC_STAGE guards from MachDeps This allows the stage1 compiler (which needs to run on the build platform and produce code for the host) to depend upon properties of the target. This is wrong. However, it's no more wrong than it was previously and @Erichson2314 is working on fixing this so I'm going to remove the guard so we can finally bootstrap HEAD with ghc-8.8 (see issue #17146). - - - - - 35cc5eff by Ben Gamari at 2019-10-09T16:21:15-04:00 Test - - - - - d584e3f0 by Ryan Scott at 2019-10-09T16:21:50-04:00 Use addUsedDataCons more judiciously in TcDeriv (#17324) If you derive an instance like this: ```hs deriving <...> instance Foo C ``` And the data constructors for `C` aren't in scope, then `doDerivInstErrorChecks1` throws an error. Moreover, it will _only_ throw an error if `<...>` is either `stock` or `newtype`. This is because the code that the `anyclass` or `via` strategies would generate would not require the use of the data constructors for `C`. However, `doDerivInstErrorChecks1` has another purpose. If you write this: ```hs import M (C(MkC1, ..., MkCn)) deriving <...> instance Foo C ``` Then `doDerivInstErrorChecks1` will call `addUsedDataCons` on `MkC1` through `MkCn` to ensure that `-Wunused-imports` does not complain about them. However, `doDerivInstErrorChecks1` was doing this for _every_ deriving strategy, which mean that if `<...>` were `anyclass` or `via`, then the warning about `MkC1` through `MkCn` being unused would be suppressed! The fix is simple enough: only call `addUsedDataCons` when the strategy is `stock` or `newtype`, just like the other code paths in `doDerivInstErrorChecks1`. Fixes #17324. - - - - - 30f5ac07 by Sebastian Graf at 2019-10-11T22:10:12-04:00 Much simpler language for PmCheck Simon realised that the simple language composed of let bindings, bang patterns and flat constructor patterns is enough to capture the semantics of the source pattern language that are important for pattern-match checking. Well, given that the Oracle is smart enough to connect the dots in this less informationally dense form, which it is now. So we transform `translatePat` to return a list of `PmGrd`s relative to an incoming match variable. `pmCheck` then trivially translates each of the `PmGrd`s into constraints that the oracle understands. Since we pass in the match variable, we incidentally fix #15884 (coverage checks for view patterns) through an interaction with !1746. - - - - - 166e1c2a by Stefan Schulze Frielinghaus at 2019-10-11T22:10:51-04:00 Hadrian: Take care of assembler source files Fixes #17286. - - - - - c2290596 by John Ericson at 2019-10-12T06:32:18-04:00 Simplify Configure in a few ways - No need to distinguish between gcc-llvm and clang. First of all, gcc-llvm is quite old and surely unmaintained by now. Second of all, none of the code actually care about that distinction! Now, it does make sense to consider C multiple frontends for LLVMs in the form of clang vs clang-cl (same clang, yes, but tweaked interface). But this is better handled in terms of "gccish vs mvscish" and "is LLVM", yielding 4 combinations. Therefore, I don't think it is useful saving the existing code for that. - Get the remaining CC_LLVM_BACKEND, and also TABLES_NEXT_TO_CODE in mk/config.h the normal way, rather than hacking it post-hoc. No point keeping these special cases around for now reason. - Get rid of hand-rolled `die` function and just use `AC_MSG_ERROR`. - Abstract check + flag override for unregisterised and tables next to code. Oh, and as part of the above I also renamed/combined some variables where it felt appropriate. - GccIsClang -> CcLlvmBackend. This is for `AC_SUBST`, like the other Camal case ones. It was never about gcc-llvm, or Apple's renamed clang, to be clear. - llvm_CC_FLAVOR -> CC_LLVM_BACKEND. This is for `AC_DEFINE`, like the other all-caps snake case ones. llvm_CC_FLAVOR was just silly indirection *and* an odd name to boot. - - - - - f1ce3535 by Vladislav Zavialov at 2019-10-12T06:33:05-04:00 Escape stats file command (#13676) - - - - - cd1a8808 by Vladislav Zavialov at 2019-10-12T06:33:05-04:00 Skip T13767 on Darwin The CI job fails with: +++ rts/T13676.run/T13676.run.stderr.normalised 2019-10-09 12:27:56.000000000 -0700 @@ -0,0 +1,4 @@ +dyld: Library not loaded: @rpath/libHShaskeline-0.7.5.0-ghc8.9.0.20191009.dylib + Referenced from: /Users/builder/builds/ewzE5N2p/0/ghc/ghc/inplace/lib/bin/ghc + Reason: image not found +*** Exception: readCreateProcess: '/Users/builder/builds/ewzE5N2p/0/ghc/ghc/inplace/lib/bin/ghc' '-B/Users/builder/builds/ewzE5N2p/0/ghc/ghc/inplace/lib' '-e' ''/''$'/'' == '/''/x0024'/''' +RTS '-tT13676.t' (exit -6): failed Unable to reproduce locally. - - - - - 0a338264 by Ryan Scott at 2019-10-12T06:33:42-04:00 Use newDFunName for both manual and derived instances (#17339) Issue #17339 was caused by using a slightly different version of `newDFunName` for derived instances that, confusingly enough, did not take all arguments to the class into account when generating the `DFun` name. I cannot think of any good reason for doing this, so this patch uses `newDFunName` uniformly for both derived instances and manually written instances alike. Fixes #17339. - - - - - c50e4c92 by Simon Peyton Jones at 2019-10-12T13:35:24-04:00 Fix validity checking for inferred types GHC is suposed to uphold the principle that an /inferred/ type for a let-binding should obey the rules for that module. E.g. we should only accept an inferred higher rank type if we have RankNTypes on. But we were failing to check this: TcValidity.checkValidType allowed arbitrary rank for inferred types. This patch fixes the bug. It might in principle cause some breakage, but if so that's good: the user should add RankNTypes and/or a manual signature. (And almost every package has explicit user signatures for all top-level things anyway.) Let's see. Fixes #17213. Metric Decrease: T10370 - - - - - 226d86d2 by Simon Peyton Jones at 2019-10-12T13:36:02-04:00 Do not add a 'solved dict' for quantified constraints GHC has a wonderful-but-delicate mechanism for building recursive dictionaries by adding a goal to the "solved dictionaries" before solving the sub-goals. See Note [Solved dictionaries] in TcSMonad Ticket #17267 showed that if you use this mechanism for local /quantified/ constraints you can get a loop -- or even unsafe coerce. This patch fixes the bug. Specifically * Make TcSMonad.addSolvedDict be conditional on using a /top level/ instance, not a quantified one. * Moreover, we /also/ don't want to add a solved dict for equalities (a~b). * Add lots more comments to Note [Solved dictionaries] to explain the above cryptic stuff. * Extend InstanceWhat to identify those strange built-in equality instances. A couple of other things along the way * Delete the unused Type.isIPPred_maybe. * Stop making addSolvedDict conditional on not being an impolicit parameter. This comes from way back. But it's irrelevant now because IP dicts are never solved via an instance. - - - - - 5ab1a28d by nineonine at 2019-10-13T06:31:40-04:00 Template Haskell: make unary tuples legal (#16881) - - - - - c1bd07cd by Andreas Klebinger at 2019-10-13T06:32:19-04:00 Fix #17334 where NCG did not properly update the CFG. Statements can change the basic block in which instructions are placed during instruction selection. We have to keep track of this switch of the current basic block as we need this information in order to properly update the CFG. This commit implements this change and fixes #17334. We do so by having stmtToInstr return the new block id if a statement changed the basic block. - - - - - 1eda9f28 by Takenobu Tani at 2019-10-13T19:06:02-04:00 users-guide: Add GHCi's ::<builtin-command> form This commit explicitly adds description about double colon command of GHCi. [skip ci] - - - - - 27145351 by Takenobu Tani at 2019-10-13T19:06:40-04:00 Add GHCi help message for :def! and :: commands - - - - - 78463fc5 by Ryan Scott at 2019-10-14T08:38:36-04:00 Add docs/users_guide/.log to .gitignore When the users guide fails to build (as in #17346), a `docs/users_guide/.log` file will be generated with contents that look something like this: ``` WARNING: unknown config value 'latex_paper_size' in override, ignoring /home/rgscott/Software/ghc5/docs/users_guide/ghci.rst:3410: WARNING: u'ghc-flag' reference target not found: -pgmo ?option? /home/rgscott/Software/ghc5/docs/users_guide/ghci.rst:3410: WARNING: u'ghc-flag' reference target not found: -pgmo ?port? Encoding error: 'ascii' codec can't encode character u'\u27e8' in position 132: ordinal not in range(128) The full traceback has been saved in /tmp/sphinx-err-rDF2LX.log, if you want to report the issue to the developers. ``` This definitely should not be checked in to version control, so let's add this to `.gitignore`. - - - - - 4aba72d6 by Ryan Scott at 2019-10-14T08:39:12-04:00 Mention changes from #16980, #17213 in 8.10.1 release notes The fixes for these issues both have user-facing consequences, so it would be good to mention them in the release notes for GHC 8.10.1. While I'm in town, also mention `UnboxedSums` in the release notes entry related to `-fobject-code`. - - - - - 0ca044fd by Ben Gamari at 2019-10-14T08:39:48-04:00 gitlab-ci: Move hadrian-ghc-in-ghci job first This is a very cheap job and can catch a number of "easy" failure modes (e.g. missing imports in the compiler). Let's run it first. - - - - - a2d3594c by Ryan Scott at 2019-10-15T01:35:34-04:00 Refactor some cruft in TcDerivInfer.inferConstraints The latest installment in my quest to clean up the code in `TcDeriv*`. This time, my sights are set on `TcDerivInfer.inferConstraints`, which infers the context for derived instances. This function is a wee bit awkward at the moment: * It's not terribly obvious from a quick glance, but `inferConstraints` is only ever invoked when using the `stock` or `anyclass` deriving strategies, as the code for inferring the context for `newtype`- or `via`-derived instances is located separately in `mk_coerce_based_eqn`. But there's no good reason for things to be this way, so I moved this code from `mk_coerce_based_eqn` to `inferConstraints` so that everything related to inferring instance contexts is located in one place. * In this process, I discovered that the Haddocks for the auxiliary function `inferConstraintsDataConArgs` are completely wrong. It claims that it handles both `stock` and `newtype` deriving, but this is completely wrong, as discussed above—it only handles `stock`. To rectify this, I renamed this function to `inferConstraintsStock` to reflect its actual purpose and created a new `inferConstraintsCoerceBased` function to specifically handle `newtype` (and `via`) deriving. Doing this revealed some opportunities for further simplification: * Removing the context-inference–related code from `mk_coerce_based_eqn` made me realize that the overall structure of the function is basically identical to `mk_originative_eqn`. In fact, I was easily able to combine the two functions into a single `mk_eqn_from_mechanism` function. As part of this merger, I now invoke `atf_coerce_based_error_checks` from `doDerivInstErrorChecks1`. * I discovered that GHC defined this function: ```hs typeToTypeKind = liftedTypeKind `mkVisFunTy` liftedTypeKind ``` No fewer than four times in different modules. I consolidated all of these definitions in a single location in `TysWiredIn`. - - - - - 426b0ddc by Ryan Scott at 2019-10-15T01:36:14-04:00 Don't skip validity checks for built-in classes (#17355) Issue #17355 occurred because the control flow for `TcValidity.check_valid_inst_head` was structured in such a way that whenever it checked a special, built-in class (like `Generic` or `HasField`), it would skip the most important check of all: `checkValidTypePats`, which rejects nonsense like this: ```hs instance Generic (forall a. a) ``` This fixes the issue by carving out `checkValidTypePats` from `check_valid_inst_head` so that `checkValidTypePats` is always invoked. `check_valid_inst_head` has also been renamed to `check_special_inst_head` to reflect its new purpose of _only_ checking for instances headed by special classes. Fixes #17355. - - - - - a55b8a65 by Alp Mestanogullari at 2019-10-15T18:41:18-04:00 iface: export a few more functions from BinIface - - - - - 9c11f817 by Ben Gamari at 2019-10-15T18:41:54-04:00 hadrian: Add support for bindist compressors other than Xz Fixes #17351. - - - - - 535a88e1 by klebinger.andreas at gmx.at at 2019-10-16T07:04:21-04:00 Add loop level analysis to the NCG backend. For backends maintaining the CFG during codegen we can now find loops and their nesting level. This is based on the Cmm CFG and dominator analysis. As a result we can estimate edge frequencies a lot better for methods, resulting in far better code layout. Speedup on nofib: ~1.5% Increase in compile times: ~1.9% To make this feasible this commit adds: * Dominator analysis based on the Lengauer-Tarjan Algorithm. * An algorithm estimating global edge frequences from branch probabilities - In CFG.hs A few static branch prediction heuristics: * Expect to take the backedge in loops. * Expect to take the branch NOT exiting a loop. * Expect integer vs constant comparisons to be false. We also treat heap/stack checks special for branch prediction to avoid them being treated as loops. - - - - - cc2bda50 by adithyaov at 2019-10-16T07:05:01-04:00 Compiling with -S and -fno-code no longer panics (fixes #17143) - - - - - 19641957 by Takenobu Tani at 2019-10-16T07:05:41-04:00 testsuite: Add test for #8305 This is a test for the current algorithm of GHCi command name resolution. I add this test in preparation for updating GHCi command name resolution. For the current algorithm, see https://downloads.haskell.org/ghc/latest/docs/html/users_guide/ghci.html#the-ghci-files - - - - - 6ede3554 by Sebastian Graf at 2019-10-16T07:06:20-04:00 Infer rho-types instead of sigma-types in guard BindStmts and TransStmts In #17343 we saw that we didn't handle the pattern guard `!_ <- undefined` correctly: The `undefined` was never evaluated. Indeed, elaboration failed to insert the invisible type aruments to `undefined`. So `undefined` was trivially a normal-form and in turn never entered. The problem is that we used to infer a sigma-type for the RHS of the guard, the leading qualifiers of which will never be useful in a pattern match situation. Hence we infer a rho-type now. Fixes #17343. - - - - - 798037a1 by John Ericson at 2019-10-16T07:06:58-04:00 Delete ghctags cabal file It came back to life in 381c3ae31b68019177f1cd20cb4da2f9d3b7d6c6 by mistake. - - - - - 51fad9e6 by Richard Eisenberg at 2019-10-16T15:58:58-04:00 Break up TcRnTypes, among other modules. This introduces three new modules: - basicTypes/Predicate.hs describes predicates, moving this logic out of Type. Predicates don't really exist in Core, and so don't belong in Type. - typecheck/TcOrigin.hs describes the origin of constraints and types. It was easy to remove from other modules and can often be imported instead of other, scarier modules. - typecheck/Constraint.hs describes constraints as used in the solver. It is taken from TcRnTypes. No work other than module splitting is in this patch. This is the first step toward homogeneous equality, which will rely more strongly on predicates. And homogeneous equality is the next step toward a dependently typed core language. - - - - - 11d4fc50 by Ben Gamari at 2019-10-16T15:59:52-04:00 hadrian: Introduce enableDebugInfo flavour transformer Also refactor things a bit to eliminate repetition. - - - - - deb96399 by Ryan Scott at 2019-10-16T16:00:29-04:00 Make Coverage.TM a newtype - - - - - 42ebc3f6 by Brian Wignall at 2019-10-16T16:01:06-04:00 Add hyperlinks to PDF/HTML documentation; closes #17342 - - - - - b15a7fb8 by Ben Gamari at 2019-10-17T01:03:11-04:00 testsuite: Ensure that makefile tests get run Previously `makefile_test` and `run_command` tests could easily end up in a situation where they wouldn't be run if the user used the `only_ways` modifier. The reason is to build the set of a ways to run the test in we first start with a candidate set determined by the test type (e.g. `makefile_test`, `compile_run`, etc.) and then filter that set with the constraints given by the test's modifiers. `makefile_test` and `run_command` tests' candidate sets were simply `{normal}`, and consequently most uses of `only_ways` would result in the test being never run. To avoid this we rather use all ways as the candidate sets for these test types. This may result in a few more testcases than we would like (given that some `run_command` tests are insensitive to way) but this can be fixed by adding modifiers and we would much rather run too many tests than too few. This fixes #16042 and a number of other tests afflicted by the same issue. However, there were a few cases that required special attention: * `T14028` is currently failing and is therefore marked as broken due to #17300 * `T-signals-child` is fragile in the `threaded1` and `threaded2` ways (tracked in #17307) - - - - - 4efdda90 by Richard Eisenberg at 2019-10-17T01:03:51-04:00 Tiny fixes to comments around flattening. - - - - - c4c9904b by Ben Gamari at 2019-10-17T01:04:26-04:00 testsuite: Assert that testsuite ways are known This ensures that all testsuite way names given to `omit_ways`, `only_ways`, etc. are known ways. - - - - - 697be2b6 by Ömer Sinan Ağacan at 2019-10-18T15:26:53-04:00 rts/GC: Add an obvious assertion during block initialization Namely ensure that block descriptors are initialized with valid generation numbers. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - 61d2ed42 by Ben Gamari at 2019-10-18T15:26:53-04:00 rts: Add Note explaining applicability of selector optimisation depth limit This was slightly non-obvious so a note seems deserved. - - - - - 11395037 by Ben Gamari at 2019-10-18T15:26:53-04:00 rts/Capability: A few documentation comments - - - - - 206f782a by Ben Gamari at 2019-10-18T15:26:53-04:00 rts: Give stack flags proper macros This were previously quite unclear and will change a bit under the non-moving collector so let's clear this up now. - - - - - 81d4675e by Ben Gamari at 2019-10-18T15:26:53-04:00 rts/GC: Refactor gcCAFs - - - - - 4d674c4e by Ben Gamari at 2019-10-18T15:26:53-04:00 rts: Fix macro parenthesisation - - - - - bfcafd39 by Ben Gamari at 2019-10-18T15:27:42-04:00 rts/Schedule: Allow synchronization without holding a capability The concurrent mark-and-sweep will be performed by a GHC task which will not hold a capability. This is necessary to avoid a concurrent mark from interfering with minor generation collections. However, the major collector must synchronize with the mutators at the end of marking to flush their update remembered sets. This patch extends the `requestSync` mechanism used to synchronize garbage collectors to allow synchronization without holding a capability. This change is fairly straightforward as the capability was previously only required for two reasons: 1. to ensure that we don't try to re-acquire a capability that we the sync requestor already holds. 2. to provide a way to suspend and later resume the sync request if there is already a sync pending. When synchronizing without holding a capability we needn't worry about consideration (1) at all. (2) is slightly trickier and may happen, for instance, when a capability requests a minor collection and shortly thereafter the non-moving mark thread requests a post-mark synchronization. In this case we need to ensure that the non-moving mark thread suspends his request until after the minor GC has concluded to avoid dead-locking. For this we introduce a condition variable, `sync_finished_cond`, which a non-capability-bearing requestor will wait on and which is signalled after a synchronization or GC has finished. - - - - - 921e4e36 by Ömer Sinan Ağacan at 2019-10-18T15:27:56-04:00 rts/BlockAlloc: Allow aligned allocation requests This implements support for block group allocations which are aligned to an integral number of blocks. This will be used by the nonmoving garbage collector, which uses the block allocator to allocate the segments which back its heap. These segments are a fixed number of blocks in size, with each segment being aligned to the segment size boundary. This allows us to easily find the segment metadata stored at the beginning of the segment. - - - - - 4b431f33 by Tamar Christina at 2019-10-20T16:21:10+01:00 Windows: Update tarballs to GCC 9.2 and remove MAX_PATH limit. - - - - - 8057ac96 by Ben Gamari at 2019-10-20T21:15:14-04:00 Merge branches 'wip/gc/sync-without-capability' and 'wip/gc/aligned-block-allocation' into wip/gc/preparation - - - - - 32500f64 by Ömer Sinan Ağacan at 2019-10-20T21:15:37-04:00 rts/StableName: Expose FOR_EACH_STABLE_NAME, freeSnEntry, SNT_size These will be needed when we implement sweeping in the nonmoving collector. - - - - - 4be5152a by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Disable aggregate-return warnings from gcc This warning is a bit of a relic; there is little reason to avoid aggregate return values in 2019. - - - - - 04471c4f by Ömer Sinan Ağacan at 2019-10-20T21:15:37-04:00 rts/Scav: Expose scavenging functions To keep the non-moving collector nicely separated from the moving collector its scavenging phase will live in another file, `NonMovingScav.c`. However, it will need to use these functions so let's expose them. - - - - - 6ff29c06 by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Introduce flag to enable the nonmoving old generation This flag will enable the use of a non-moving oldest generation. - - - - - b3ef2d1a by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Introduce debug flag for non-moving GC - - - - - 68e0647f by Ömer Sinan Ağacan at 2019-10-20T21:15:37-04:00 rts: Non-concurrent mark and sweep This implements the core heap structure and a serial mark/sweep collector which can be used to manage the oldest-generation heap. This is the first step towards a concurrent mark-and-sweep collector aimed at low-latency applications. The full design of the collector implemented here is described in detail in a technical note B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell Compiler" (2018) The basic heap structure used in this design is heavily inspired by K. Ueno & A. Ohori. "A fully concurrent garbage collector for functional programs on multicore processors." /ACM SIGPLAN Notices/ Vol. 51. No. 9 (presented by ICFP 2016) This design is intended to allow both marking and sweeping concurrent to execution of a multi-core mutator. Unlike the Ueno design, which requires no global synchronization pauses, the collector introduced here requires a stop-the-world pause at the beginning and end of the mark phase. To avoid heap fragmentation, the allocator consists of a number of fixed-size /sub-allocators/. Each of these sub-allocators allocators into its own set of /segments/, themselves allocated from the block allocator. Each segment is broken into a set of fixed-size allocation blocks (which back allocations) in addition to a bitmap (used to track the liveness of blocks) and some additional metadata (used also used to track liveness). This heap structure enables collection via mark-and-sweep, which can be performed concurrently via a snapshot-at-the-beginning scheme (although concurrent collection is not implemented in this patch). The mark queue is a fairly straightforward chunked-array structure. The representation is a bit more verbose than a typical mark queue to accomodate a combination of two features: * a mark FIFO, which improves the locality of marking, reducing one of the major overheads seen in mark/sweep allocators (see [1] for details) * the selector optimization and indirection shortcutting, which requires that we track where we found each reference to an object in case we need to update the reference at a later point (e.g. when we find that it is an indirection). See Note [Origin references in the nonmoving collector] (in `NonMovingMark.h`) for details. Beyond this the mark/sweep is fairly run-of-the-mill. [1] R. Garner, S.M. Blackburn, D. Frampton. "Effective Prefetch for Mark-Sweep Garbage Collection." ISMM 2007. Co-Authored-By: Ben Gamari <ben at well-typed.com> - - - - - c7e73d12 by Ben Gamari at 2019-10-20T21:15:37-04:00 testsuite: Add nonmoving WAY This simply runs the compile_and_run tests with `-xn`, enabling the nonmoving oldest generation. - - - - - f8f77a07 by Ben Gamari at 2019-10-20T21:15:37-04:00 rts: Mark binder as const - - - - - bd8e3ff4 by Ben Gamari at 2019-10-20T21:15:52-04:00 rts: Implement concurrent collection in the nonmoving collector This extends the non-moving collector to allow concurrent collection. The full design of the collector implemented here is described in detail in a technical note B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell Compiler" (2018) This extension involves the introduction of a capability-local remembered set, known as the /update remembered set/, which tracks objects which may no longer be visible to the collector due to mutation. To maintain this remembered set we introduce a write barrier on mutations which is enabled while a concurrent mark is underway. The update remembered set representation is similar to that of the nonmoving mark queue, being a chunked array of `MarkEntry`s. Each `Capability` maintains a single accumulator chunk, which it flushed when it (a) is filled, or (b) when the nonmoving collector enters its post-mark synchronization phase. While the write barrier touches a significant amount of code it is conceptually straightforward: the mutator must ensure that the referee of any pointer it overwrites is added to the update remembered set. However, there are a few details: * In the case of objects with a dirty flag (e.g. `MVar`s) we can exploit the fact that only the *first* mutation requires a write barrier. * Weak references, as usual, complicate things. In particular, we must ensure that the referee of a weak object is marked if dereferenced by the mutator. For this we (unfortunately) must introduce a read barrier, as described in Note [Concurrent read barrier on deRefWeak#] (in `NonMovingMark.c`). * Stable names are also a bit tricky as described in Note [Sweeping stable names in the concurrent collector] (`NonMovingSweep.c`). We take quite some pains to ensure that the high thread count often seen in parallel Haskell applications doesn't affect pause times. To this end we allow thread stacks to be marked either by the thread itself (when it is executed or stack-underflows) or the concurrent mark thread (if the thread owning the stack is never scheduled). There is a non-trivial handshake to ensure that this happens without racing which is described in Note [StgStack dirtiness flags and concurrent marking]. Co-Authored-by: Ömer Sinan Ağacan <omer at well-typed.com> - - - - - dd1b4fdd by Ben Gamari at 2019-10-20T21:15:52-04:00 Nonmoving: Disable memory inventory with concurrent collection - - - - - 4a44ab33 by Ben Gamari at 2019-10-20T21:15:52-04:00 rts: Shrink size of STACK's dirty and marking fields - - - - - 10373416 by Ben Gamari at 2019-10-20T21:15:52-04:00 Don't cleanup until we've stopped the collector This requires that we break nonmovingExit into two pieces since we need to first stop the collector to relinquish any capabilities, then we need to shutdown the scheduler, then we need to free the nonmoving allocators. - - - - - 26c3827f by Ben Gamari at 2019-10-21T11:43:54-04:00 Nonmoving: Ensure write barrier vanishes in non-threaded RTS - - - - - 17e5a032 by Ben Gamari at 2019-10-21T11:43:54-04:00 ThreadPaused: Add barrer on updated thunk - - - - - 8ea316da by David Eichmann at 2019-10-22T02:07:48-04:00 CI: Always dump performance metrics. - - - - - aa31ceaf by Matthew Bauer at 2019-10-22T02:39:01-04:00 Replace freebsd-gnueabihf with freebsd FreeBSD does not support GNU libc, so it makes no sense to use this triple. Most likely previous builds were just using the FreeBSD libc instead of gnueabihf. To fix this, we should just use armv6-unknown-freebsd and armv7-unknown-freebsd triples. Note that both of these are actually "soft-float", not "hard-float". FreeBSD has never officially released hard-float arm32: https://wiki.freebsd.org/ARMTier1 - - - - - fd8b666a by Stefan Schulze Frielinghaus at 2019-10-22T02:39:03-04:00 Implement s390x LLVM backend. This patch adds support for the s390x architecture for the LLVM code generator. The patch includes a register mapping of STG registers onto s390x machine registers which enables a registerised build. - - - - - 2d2cc76f by Tilman Blumhagen at 2019-10-22T02:39:04-04:00 Documentation for (&&) and (&&) states that they are lazy in their second argument (fixes #17354) - - - - - 06d51c4e by Ben Gamari at 2019-10-22T12:13:36-04:00 Fix unregisterised build This required some fiddling around with the location of forward declarations since the C sources generated by GHC's C backend only includes Stg.h. - - - - - 912e440e by Ben Gamari at 2019-10-22T12:17:00-04:00 rts: Tracing support for nonmoving collection events This introduces a few events to mark key points in the nonmoving garbage collection cycle. These include: * `EVENT_CONC_MARK_BEGIN`, denoting the beginning of a round of marking. This may happen more than once in a single major collection since we the major collector iterates until it hits a fixed point. * `EVENT_CONC_MARK_END`, denoting the end of a round of marking. * `EVENT_CONC_SYNC_BEGIN`, denoting the beginning of the post-mark synchronization phase * `EVENT_CONC_UPD_REM_SET_FLUSH`, indicating that a capability has flushed its update remembered set. * `EVENT_CONC_SYNC_END`, denoting that all mutators have flushed their update remembered sets. * `EVENT_CONC_SWEEP_BEGIN`, denoting the beginning of the sweep portion of the major collection. * `EVENT_CONC_SWEEP_END`, denoting the end of the sweep portion of the major collection. - - - - - 9f42cd81 by Ben Gamari at 2019-10-22T12:17:00-04:00 rts: Introduce non-moving heap census This introduces a simple census of the non-moving heap (not to be confused with the heap census used by the heap profiler). This collects basic heap usage information (number of allocated and free blocks) which is useful when characterising fragmentation of the nonmoving heap. - - - - - 711837cc by Ben Gamari at 2019-10-22T12:17:00-04:00 rts/Eventlog: More descriptive error message - - - - - 0d31819e by Ben Gamari at 2019-10-22T12:17:00-04:00 Allow census without live word count Otherwise the census is unsafe when mutators are running due to concurrent mutation. - - - - - 6f173181 by Ben Gamari at 2019-10-22T12:17:00-04:00 NonmovingCensus: Emit samples to eventlog - - - - - 13dd78dd by Ben Gamari at 2019-10-22T12:18:33-04:00 Nonmoving: Allow aging and refactor static objects logic This commit does two things: * Allow aging of objects during the preparatory minor GC * Refactor handling of static objects to avoid the use of a hashtable - - - - - 7b79e8b4 by Ben Gamari at 2019-10-22T12:18:33-04:00 Disable aging when doing deadlock detection GC - - - - - 8fffe12b by Ben Gamari at 2019-10-22T12:18:33-04:00 More comments for aging - - - - - 039d2906 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Eliminate integer division in nonmovingBlockCount Perf showed that the this single div was capturing up to 10% of samples in nonmovingMark. However, the overwhelming majority of cases is looking at small block sizes. These cases we can easily compute explicitly, allowing the compiler to turn the division into a significantly more efficient division-by-constant. While the increase in source code looks scary, this all optimises down to very nice looking assembler. At this point the only remaining hotspots in nonmovingBlockCount are due to memory access. - - - - - d15ac82d by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Allocate mark queues in larger block groups - - - - - 26d2d331 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMovingMark: Optimize representation of mark queue This shortens MarkQueueEntry by 30% (one word) - - - - - e5eda61e by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Optimize bitmap search during allocation Use memchr instead of a open-coded loop. This is nearly twice as fast in a synthetic benchmark. - - - - - dacf4cae by Ben Gamari at 2019-10-22T12:18:39-04:00 rts: Add prefetch macros - - - - - 786c52d2 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Prefetch when clearing bitmaps Ensure that the bitmap of the segmentt that we will clear next is in cache by the time we reach it. - - - - - 0387df5b by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Inline nonmovingClearAllBitmaps - - - - - e893877e by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Fuse sweep preparation into mark prep - - - - - e6f6823f by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Pre-fetch during mark This improved overall runtime on nofib's constraints test by nearly 10%. - - - - - 56c5ebdc by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Prefetch segment header - - - - - 19bfe460 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Optimise allocator cache behavior Previously we would look at the segment header to determine the block size despite the fact that we already had the block size at hand. - - - - - 53a1a27e by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMovingMark: Eliminate redundant check_in_nonmoving_heaps - - - - - b967e470 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Don't do major GC if one is already running Previously we would perform a preparatory moving collection, resulting in many things being added to the mark queue. When we finished with this we would realize in nonmovingCollect that there was already a collection running, in which case we would simply not run the nonmoving collector. However, it was very easy to end up in a "treadmilling" situation: all subsequent GC following the first failed major GC would be scheduled as major GCs. Consequently we would continuously feed the concurrent collector with more mark queue entries and it would never finish. This patch aborts the major collection far earlier, meaning that we avoid adding nonmoving objects to the mark queue and allowing the concurrent collector to finish. - - - - - 3bc172a4 by Ben Gamari at 2019-10-22T12:18:39-04:00 NonMoving: Clean mut_list - - - - - 8e79e2a9 by Ben Gamari at 2019-10-22T12:18:39-04:00 Unconditionally flush update remembered set during minor GC Flush the update remembered set. The goal here is to flush periodically to ensure that we don't end up with a thread who marks their stack on their local update remembered set and doesn't flush until the nonmoving sync period as this would result in a large fraction of the heap being marked during the sync pause. - - - - - b281e80b by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Add nonmoving_thr way - - - - - 07987957 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Add nonmoving_thr_ghc way This uses the nonmoving collector when compiling the testcases. - - - - - 01fd0242 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Don't run T15892 in nonmoving ways The nonmoving GC doesn't support `+RTS -G1`, which this test insists on. - - - - - 097f4fd0 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Nonmoving collector doesn't support -G1 - - - - - 4b91dd25 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Ensure that threaded tests are run in nonmoving_thr - - - - - 78ce35b9 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: bug1010 requires -c, which isn't supported by nonmoving - - - - - 6e97cc47 by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Skip T15892 in nonmoving_thr_ghc - - - - - 5ce853c8 by Ben Gamari at 2019-10-22T12:18:44-04:00 ghc-heap: Skip heap_all test with debugged RTS The debugged RTS initializes the heap with 0xaa, which breaks the (admittedly rather fragile) assumption that uninitialized fields are set to 0x00: ``` Wrong exit code for heap_all(nonmoving)(expected 0 , actual 1 ) Stderr ( heap_all ): heap_all: user error (assertClosuresEq: Closures do not match Expected: FunClosure {info = StgInfoTable {entry = Nothing, ptrs = 0, nptrs = 1, tipe = FUN_0_1, srtlen = 0, code = Nothing}, ptrArgs = [], dataArgs = [0]} Actual: FunClosure {info = StgInfoTable {entry = Nothing, ptrs = 0, nptrs = 1, tipe = FUN_0_1, srtlen = 1032832, code = Nothing}, ptrArgs = [], dataArgs = [12297829382473034410]} CallStack (from HasCallStack): assertClosuresEq, called at heap_all.hs:230:9 in main:Main ) ``` - - - - - 6abefce7 by Ben Gamari at 2019-10-22T12:18:44-04:00 Skip ghc_heap_all test in nonmoving ways - - - - - 99baff8c by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Don't run T9630 in nonmoving ways The nonmoving collector doesn't support -G1 - - - - - 25ae8f7d by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Don't run T7160 in nonmoving_thr ways The nonmoving way finalizes things in a different order. - - - - - 8cab149b by Ben Gamari at 2019-10-22T12:18:44-04:00 testsuite: Mark length001 as failing under nonmoving ways This is consistent with the other unoptimized ways. - - - - - 5b130b3d by Ben Gamari at 2019-10-22T12:18:46-04:00 Merge branches 'wip/gc/optimize' and 'wip/gc/test' into wip/gc/everything - - - - - 246ce2af by Ömer Sinan Ağacan at 2019-10-22T12:20:15-04:00 NonMoving: Implement indirection shortcutting This allows indirection chains residing in the non-moving heap to be shorted-out. - - - - - 875861ef by Ömer Sinan Ağacan at 2019-10-22T12:20:15-04:00 NonMoving: Implement selector optimisation - - - - - c72e84c6 by Ben Gamari at 2019-10-22T12:20:15-04:00 NonMovingMark: Handle INDs left by shortcutting - - - - - 0f8fd3c6 by Ömer Sinan Ağacan at 2019-10-22T12:20:15-04:00 NonMoving: Implement -xns to disable selector optimization - - - - - c936a245 by Ben Gamari at 2019-10-22T12:20:37-04:00 NonMoving: Introduce nonmovingSegmentLogBlockSize acccessor This will allow us to easily move the block size elsewhere. - - - - - 6dcef5ee by Ben Gamari at 2019-10-22T12:20:37-04:00 NonMoving: Move block size to block descriptor - - - - - dd8d1b49 by Ben Gamari at 2019-10-22T12:20:37-04:00 NonMoving: Move next_free_snap to block descriptor - - - - - 116e4646 by Ben Gamari at 2019-10-22T12:20:46-04:00 NonMoving: Add summarizing Note - - - - - 22eee2bc by Ben Gamari at 2019-10-22T12:20:48-04:00 Merge branches 'wip/gc/segment-header-to-bdescr' and 'wip/gc/docs' into wip/gc/everything2 - - - - - 3a862703 by Ömer Sinan Ağacan at 2019-10-22T18:56:32-04:00 rts: COMPACT_NFDATA support for the nonmoving collector This largely follows the model used for large objects, with appropriate adjustments made to account for references in the sharing deduplication hashtable. - - - - - 7c35d39b by Ben Gamari at 2019-10-22T18:56:32-04:00 rts: Mark nonmoving GC paths in moving collector as unlikely The expectation here is that the nonmoving GC is latency-centric, whereas the moving GC emphasizes throughput. Therefore we give the latter the benefit of better static branch prediction. - - - - - 91109404 by Ben Gamari at 2019-10-22T18:57:27-04:00 nonmoving: Trace GC preparation steps - - - - - a69b28f4 by Ben Gamari at 2019-10-22T18:57:27-04:00 nonmoving: Don't do two passes over large and compact object lists Previously we would first move the new objects to their appropriate non-moving GC list, then do another pass over that list to clear their mark bits. This is needlessly expensive. First clear the mark bits of the existing objects, then add the newly evacuated objects and, at the same time, clear their mark bits. This cuts the preparatory GC time in half for the Pusher benchmark with a large queue size. - - - - - 984745b0 by Ben Gamari at 2019-10-22T18:57:27-04:00 nonmoving: Upper-bound time we hold SM_MUTEX for during sweep - - - - - 96c5411a by David Feuer at 2019-10-23T05:58:37-04:00 Use an IORef for QSemN Replace the outer `MVar` in `QSemN` with an `IORef`. This should probably be lighter, and it removes the need for `uninterruptibleMask`. Previously Differential Revision https://phabricator.haskell.org/D4896 - - - - - faa30dcb by Andreas Klebinger at 2019-10-23T05:58:43-04:00 Warn about missing profiled libs when using the Interpreter. When GHC itself, or it's interpreter is profiled we need to load profiled libraries as well. This requirement is not always obvious, especially when TH implicilty uses the interpreter. When the libs were not found we fall back to assuming the are in a DLL. This is usually not the case so now we warn users when we do so. This makes it more obvious what is happening and gives users a way to fix the issue. This fixes #17121. - - - - - 1cd3fa29 by Richard Eisenberg at 2019-10-23T05:58:46-04:00 Implement a coverage checker for injectivity This fixes #16512. There are lots of parts of this patch: * The main payload is in FamInst. See Note [Coverage condition for injective type families] there for the overview. But it doesn't fix the bug. * We now bump the reduction depth every time we discharge a CFunEqCan. See Note [Flatten when discharging CFunEqCan] in TcInteract. * Exploration of this revealed a new, easy to maintain invariant for CTyEqCans. See Note [Almost function-free] in TcRnTypes. * We also realized that type inference for injectivity was a bit incomplete. This means we exchanged lookupFlattenTyVar for rewriteTyVar. See Note [rewriteTyVar] in TcFlatten. The new function is monadic while the previous one was pure, necessitating some faff in TcInteract. Nothing too bad. * zonkCt did not maintain invariants on CTyEqCan. It's not worth the bother doing so, so we just transmute CTyEqCans to CNonCanonicals. * The pure unifier was finding the fixpoint of the returned substitution, even when doing one-way matching (in tcUnifyTysWithTFs). Fixed now. Test cases: typecheck/should_fail/T16512{a,b} - - - - - 900cf195 by Alp Mestanogullari at 2019-10-23T05:58:48-04:00 compiler: introduce DynFlags plugins They have type '[CommandLineOpts] -> Maybe (DynFlags -> IO DynFlags)'. All plugins that supply a non-Nothing 'dynflagsPlugin' will see their updates applied to the current DynFlags right after the plugins are loaded. One use case for this is to superseede !1580 for registering hooks from a plugin. Frontend/parser plugins were considered to achieve this but they respectively conflict with how this plugin is going to be used and don't allow overriding/modifying the DynFlags, which is how hooks have to be registered. This commit comes with a test, 'test-hook-plugin', that registers a "fake" meta hook that replaces TH expressions with the 0 integer literal. - - - - - a19c7d17 by Ryan Scott at 2019-10-23T05:58:49-04:00 Reify oversaturated data family instances correctly (#17296) `TcSplice` was not properly handling oversaturated data family instances, such as the example in #17296, as it dropped arguments due to carelessly zipping data family instance arguments with `tyConTyVars`. For data families, the number of `tyConTyVars` can sometimes be less than the number of arguments it can accept in a data family instance due to the fact that data family instances can be oversaturated. To account for this, `TcSplice.mkIsPolyTvs` has now been renamed to `tyConArgsPolyKinded` and now factors in `tyConResKind` in addition to `tyConTyVars`. I've also added `Note [Reified instances and explicit kind signatures]` which explains the various subtleties in play here. Fixes #17296. - - - - - 9b2a5008 by Ben Gamari at 2019-10-23T05:58:50-04:00 testsuite: Don't run T7653 in ghci and profiled ways Currently this routinely fails in the i386 job. See #7653. - - - - - b521e8b6 by Ömer Sinan Ağacan at 2019-10-23T05:58:57-04:00 Refactor Compact.c: - Remove forward declarations - Introduce UNTAG_PTR and GET_PTR_TAG for dealing with pointer tags without having to cast arguments to StgClosure* - Remove dead code - Use W_ instead of StgWord - Use P_ instead of StgPtr - - - - - 17987a4b by Matthew Pickering at 2019-10-23T05:58:58-04:00 eventlog: Dump cost centre stack on each sample With this change it is possible to reconstruct the timing portion of a `.prof` file after the fact. By logging the stacks at each time point a more precise executation trace of the program can be observed rather than all identical cost centres being identified in the report. There are two new events: 1. `EVENT_PROF_BEGIN` - emitted at the start of profiling to communicate the tick interval 2. `EVENT_PROF_SAMPLE_COST_CENTRE` - emitted on each tick to communicate the current call stack. Fixes #17322 - - - - - 4798f3b9 by Takenobu Tani at 2019-10-23T05:59:00-04:00 Allow command name resolution for GHCi commands with option `!` #17345 This commit allows command name resolution for GHCi commands with option `!` as follows: ghci> :k! Int Int :: * = Int This commit changes implementation as follows: Before: * Prefix match with full string including the option `!` (e.g. `k!`) After (this patch): * Prefix match without option suffix `!` (e.g. `k`) * in addition, suffix match with option `!` See also #8305 and #8113 - - - - - aa778152 by Andreas Klebinger at 2019-10-23T05:59:01-04:00 Fix bug in the x86 backend involving the CFG. This is part two of fixing #17334. There are two parts to this commit: - A bugfix for computing loop levels - A bugfix of basic block invariants in the NCG. ----------------------------------------------------------- In the first bug we ended up with a CFG of the sort: [A -> B -> C] This was represented via maps as fromList [(A,B),(B,C)] and later transformed into a adjacency array. However the transformation did not include block C in the array (since we only looked at the keys of the map). This was still fine until we tried to look up successors for C and tried to read outside of the array bounds when accessing C. In order to prevent this in the future I refactored to code to include all nodes as keys in the map representation. And make this a invariant which is checked in a few places. Overall I expect this to make the code more robust as now any failed lookup will represent an error, versus failed lookups sometimes being expected and sometimes not. In terms of performance this makes some things cheaper (getting a list of all nodes) and others more expensive (adding a new edge). Overall this adds up to no noteable performance difference. ----------------------------------------------------------- Part 2: When the NCG generated a new basic block, it did not always insert a NEWBLOCK meta instruction in the stream which caused a quite subtle bug. During instruction selection a statement `s` in a block B with control of the sort: B -> C will sometimes result in control flow of the sort: ┌ < ┐ v ^ B -> B1 ┴ -> C as is the case for some atomic operations. Now to keep the CFG in sync when introducing B1 we clearly want to insert it between B and C. However there is a catch when we have to deal with self loops. We might start with code and a CFG of these forms: loop: stmt1 ┌ < ┐ .... v ^ stmtX loop ┘ stmtY .... goto loop: Now we introduce B1: ┌ ─ ─ ─ ─ ─┐ loop: │ ┌ < ┐ │ instrs v │ │ ^ .... loop ┴ B1 ┴ ┘ instrsFromX stmtY goto loop: This is simple, all outgoing edges from loop now simply start from B1 instead and the code generator knows which new edges it introduced for the self loop of B1. Disaster strikes if the statement Y follows the same pattern. If we apply the same rule that all outgoing edges change then we end up with: loop ─> B1 ─> B2 ┬─┐ │ │ └─<┤ │ │ └───<───┘ │ └───────<────────┘ This is problematic. The edge B1->B1 is modified as expected. However the modification is wrong! The assembly in this case looked like this: _loop: <instrs> _B1: ... cmpxchgq ... jne _B1 <instrs> <end _B1> _B2: ... cmpxchgq ... jne _B2 <instrs> jmp loop There is no edge _B2 -> _B1 here. It's still a self loop onto _B1. The problem here is that really B1 should be two basic blocks. Otherwise we have control flow in the *middle* of a basic block. A contradiction! So to account for this we add yet another basic block marker: _B: <instrs> _B1: ... cmpxchgq ... jne _B1 jmp _B1' _B1': <instrs> <end _B1> _B2: ... Now when inserting B2 we will only look at the outgoing edges of B1' and everything will work out nicely. You might also wonder why we don't insert jumps at the end of _B1'. There is no way another block ends up jumping to the labels _B1 or _B2 since they are essentially invisible to other blocks. View them as control flow labels local to the basic block if you'd like. Not doing this ultimately caused (part 2 of) #17334. - - - - - 1f40e68a by Ryan Yates at 2019-10-23T05:59:03-04:00 Full abort on validate failure merging `orElse`. Previously partial roll back of a branch of an `orElse` was attempted if validation failure was observed. Validation here, however, does not account for what part of the transaction observed inconsistent state. This commit fixes this by fully aborting and restarting the transaction. - - - - - 9c1f0f7c by Ben Gamari at 2019-10-23T05:59:03-04:00 Bump stm submodule - - - - - 6beea836 by Andreas Klebinger at 2019-10-23T05:59:04-04:00 Make dynflag argument for withTiming pure. 19 times out of 20 we already have dynflags in scope. We could just always use `return dflags`. But this is in fact not free. When looking at some STG code I noticed that we always allocate a closure for this expression in the heap. Clearly a waste in these cases. For the other cases we can either just modify the callsite to get dynflags or use the _D variants of withTiming I added which will use getDynFlags under the hood. - - - - - 8dd480cc by Matthew Pickering at 2019-10-23T05:59:06-04:00 Performance tests: Reduce acceptance threshold for bytes allocated tests The "new" performance testing infrastructure resets the baseline after every test so it's easy to miss gradual performance regressions over time. We should at least make these numbers smaller to catch patches which affect performance earlier. - - - - - 4af20bbc by Ben Gamari at 2019-10-23T05:59:06-04:00 users-guide: Fix :since: for -Wunused-packages Fixes #17382. - - - - - 21663693 by Ben Gamari at 2019-10-23T05:59:07-04:00 Drop duplicate -optl's from GHC invocations Previously the make build system would pass things like `-optl-optl-Wl,-x -optl-optl-Wl,noexecstack` to GHC. This would naturally result in mass confusion as GHC would pass `-optl-Wl,-x` to GCC. GCC would in turn interpret this as `-o ptl-Wl,-x`, setting the output pass of the invocation. The problem that `-optl` was added to the command-line in two places in the build system. Fix this. Fixes #17385. - - - - - bb0dc5a5 by Andreas Klebinger at 2019-10-23T05:59:07-04:00 Hadrian: Invoke ghc0 via bash when running tests to fix #17362. cmd uses RawCommand which uses Windows semantics to find the executable which sometimes seems to fail for unclear reasons. If we invoke ghc via bash then bash will find the ghc executable and the issue goes away. - - - - - 266435a7 by Ömer Sinan Ağacan at 2019-10-23T05:59:09-04:00 Add new flag for unarised STG dumps Previously -ddump-stg would dump pre and post-unarise STGs. Now we have a new flag for post-unarise STG and -ddump-stg only dumps coreToStg output. STG dump flags after this commit: - -ddump-stg: Dumps CoreToStg output - -ddump-stg-unarised: Unarise output - -ddump-stg-final: STG right before code gen (includes CSE and lambda lifting) - - - - - 8abddac8 by Ben Gamari at 2019-10-23T05:59:10-04:00 base: Add @since on GHC.IO.Handle.Lock.hUnlock Unfortunately this was introduced in base-4.11.0 (GHC 8.4.1) whereas the other locking primitives were added in base-4.10.0 (GHC 8.2.1). - - - - - 7f72b540 by Ben Gamari at 2019-10-23T14:56:46-04:00 Merge non-moving garbage collector This introduces a concurrent mark & sweep garbage collector to manage the old generation. The concurrent nature of this collector typically results in significantly reduced maximum and mean pause times in applications with large working sets. Due to the large and intricate nature of the change I have opted to preserve the fully-buildable history, including merge commits, which is described in the "Branch overview" section below. Collector design ================ The full design of the collector implemented here is described in detail in a technical note > B. Gamari. "A Concurrent Garbage Collector For the Glasgow Haskell > Compiler" (2018) This document can be requested from @bgamari. The basic heap structure used in this design is heavily inspired by > K. Ueno & A. Ohori. "A fully concurrent garbage collector for > functional programs on multicore processors." /ACM SIGPLAN Notices/ > Vol. 51. No. 9 (presented at ICFP 2016) This design is intended to allow both marking and sweeping concurrent to execution of a multi-core mutator. Unlike the Ueno design, which requires no global synchronization pauses, the collector introduced here requires a stop-the-world pause at the beginning and end of the mark phase. To avoid heap fragmentation, the allocator consists of a number of fixed-size /sub-allocators/. Each of these sub-allocators allocators into its own set of /segments/, themselves allocated from the block allocator. Each segment is broken into a set of fixed-size allocation blocks (which back allocations) in addition to a bitmap (used to track the liveness of blocks) and some additional metadata (used also used to track liveness). This heap structure enables collection via mark-and-sweep, which can be performed concurrently via a snapshot-at-the-beginning scheme (although concurrent collection is not implemented in this patch). Implementation structure ======================== The majority of the collector is implemented in a handful of files: * `rts/Nonmoving.c` is the heart of the beast. It implements the entry-point to the nonmoving collector (`nonmoving_collect`), as well as the allocator (`nonmoving_allocate`) and a number of utilities for manipulating the heap. * `rts/NonmovingMark.c` implements the mark queue functionality, update remembered set, and mark loop. * `rts/NonmovingSweep.c` implements the sweep loop. * `rts/NonmovingScav.c` implements the logic necessary to scavenge the nonmoving heap. Branch overview =============== ``` * wip/gc/opt-pause: | A variety of small optimisations to further reduce pause times. | * wip/gc/compact-nfdata: | Introduce support for compact regions into the non-moving |\ collector | \ | \ | | * wip/gc/segment-header-to-bdescr: | | | Another optimization that we are considering, pushing | | | some segment metadata into the segment descriptor for | | | the sake of locality during mark | | | | * | wip/gc/shortcutting: | | | Support for indirection shortcutting and the selector optimization | | | in the non-moving heap. | | | * | | wip/gc/docs: | |/ Work on implementation documentation. | / |/ * wip/gc/everything: | A roll-up of everything below. |\ | \ | |\ | | \ | | * wip/gc/optimize: | | | A variety of optimizations, primarily to the mark loop. | | | Some of these are microoptimizations but a few are quite | | | significant. In particular, the prefetch patches have | | | produced a nontrivial improvement in mark performance. | | | | | * wip/gc/aging: | | | Enable support for aging in major collections. | | | | * | wip/gc/test: | | | Fix up the testsuite to more or less pass. | | | * | | wip/gc/instrumentation: | | | A variety of runtime instrumentation including statistics | | / support, the nonmoving census, and eventlog support. | |/ | / |/ * wip/gc/nonmoving-concurrent: | The concurrent write barriers. | * wip/gc/nonmoving-nonconcurrent: | The nonmoving collector without the write barriers necessary | for concurrent collection. | * wip/gc/preparation: | A merge of the various preparatory patches that aren't directly | implementing the GC. | | * GHC HEAD . . . ``` - - - - - 83655b06 by Ben Gamari at 2019-10-24T08:45:41-04:00 hadrian: Warn user if hadrian build fails due to lack of threaded RTS See #16873. - - - - - 6824f29a by Ryan Scott at 2019-10-24T08:46:19-04:00 Parenthesize GADT return types in pprIfaceConDecl (#17384) We were using `pprIfaceAppArgs` instead of `pprParendIfaceAppArgs` in `pprIfaceConDecl`. Oops. Fixes #17384. - - - - - 9de3f8b1 by Ryan Scott at 2019-10-24T18:38:32-04:00 Make isTcLevPoly more conservative with newtypes (#17360) `isTcLevPoly` gives an approximate answer for when a type constructor is levity polymorphic when fully applied, where `True` means "possibly levity polymorphic" and `False` means "definitely not levity polymorphic". `isTcLevPoly` returned `False` for newtypes, which is incorrect in the presence of `UnliftedNewtypes`, leading to #17360. This patch tweaks `isTcLevPoly` to return `True` for newtypes instead. Fixes #17360. - - - - - 243c72eb by Ryan Scott at 2019-10-24T18:39:08-04:00 Mark promoted InfixT names as IsPromoted (#17394) We applied a similar fix for `ConT` in #15572 but forgot to apply the fix to `InfixT` as well. This patch fixes #17394 by doing just that. - - - - - 87175e78 by James Foster at 2019-10-25T09:01:08-04:00 Make Hadrian use -dynamic-too in the basic case This commit makes Hadrian use the `-dynamic-too` flag when the current Flavour's libraryWays contains both vanilla and dynamic, cutting down the amount of repeated work caused by separate compilation of dynamic and static files. It does this for the basic case where '.o' and '.dyn_o' files are built with one command, but does not generalise to cases like '.prof_o' and '.prof_dyn_o'. - - - - - ecd89062 by Alp Mestanogullari at 2019-10-25T09:01:47-04:00 hadrian/ci: run testsuite against a freshly produced and installed bindist - - - - - 2a16b555 by Ben Gamari at 2019-10-25T09:02:26-04:00 testsuite: Mark T13786 as fragile in unreg build Due to #17018. - - - - - 08298926 by Ben Gamari at 2019-10-25T09:02:26-04:00 testsuite: Use fragile modifier in TH_foreignInterruptible It looks like this use of `skip` snuck through my previous refactoring. - - - - - 4c7d45d1 by Brian Wignall at 2019-10-25T09:03:04-04:00 Make documentation for byteSwap16 consistent with byteSwap32 (impl is same, with s/16/32) - - - - - 02822d84 by Ben Gamari at 2019-10-25T09:03:40-04:00 aclocal: A bit of reformatting - - - - - 519f5162 by Ben Gamari at 2019-10-25T09:03:40-04:00 configure: Drop GccLT46 GCC 4.6 was released 7 years ago. I think we can finally assume that it's available. This is a simplification prompted by #15742. - - - - - acedfc8b by Ben Gamari at 2019-10-25T09:04:16-04:00 gitlab-ci: Run check-uniques during lint job - - - - - 8916e64e by Andrew Martin at 2019-10-26T05:19:38-04:00 Implement shrinkSmallMutableArray# and resizeSmallMutableArray#. This is a part of GHC Proposal #25: "Offer more array resizing primitives". Resources related to the proposal: - Discussion: https://github.com/ghc-proposals/ghc-proposals/pull/121 - Proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0025-resize-boxed.rst Only shrinkSmallMutableArray# is implemented as a primop since a library-space implementation of resizeSmallMutableArray# (in GHC.Exts) is no less efficient than a primop would be. This may be replaced by a primop in the future if someone devises a strategy for growing arrays in-place. The library-space implementation always copies the array when growing it. This commit also tweaks the documentation of the deprecated sizeofMutableByteArray#, removing the mention of concurrency. That primop is unsound even in single-threaded applications. Additionally, the non-negativity assertion on the existing shrinkMutableByteArray# primop has been removed since this predicate is trivially always true. - - - - - 1be9c35c by Roland Senn at 2019-10-26T05:20:14-04:00 Fix #14690 - :steplocal panics after break-on-error `:steplocal` enables only breakpoints in the current top-level binding. When a normal breakpoint is hit, then the module name and the break id from the `BRK_FUN` byte code allow us to access the corresponding entry in a ModBreak table. From this entry we then get the SrcSpan (see compiler/main/InteractiveEval.hs:bindLocalsAtBreakpoint). With this source-span we can then determine the current top-level binding, needed for the steplocal command. However, if we break at an exception or at an error, we don't have an BRK_FUN byte-code, so we don't have any source information. The function `bindLocalsAtBreakpoint` creates an `UnhelpfulSpan`, which doesn't allow us to determine the current top-level binding. To avoid a `panic`, we have to check for `UnhelpfulSpan` in the function `ghc/GHCi/UI.hs:stepLocalCmd`. Hence a :steplocal command after a break-on-exception or a break-on-error is not possible. - - - - - 4820af10 by Adam Sandberg Eriksson at 2019-10-26T19:53:01-04:00 hadrian: point link to ghc gitlab [skip ci] - - - - - 609c7ee6 by Ben Gamari at 2019-10-26T19:53:36-04:00 gitlab-ci: Produce ARMv7 binary distributions - - - - - 8ac49411 by Ben Gamari at 2019-10-26T19:53:36-04:00 testsuite: Skip regalloc_unit_tests unless have_ncg This is a unit test for the native code generator's register allocator; naturally. the NCG is required. - - - - - 60575596 by Ben Gamari at 2019-10-26T19:53:36-04:00 Enable PDF documentation - - - - - 417f59d4 by Ben Gamari at 2019-10-26T19:53:36-04:00 rts: Fix ARM linker includes * Prefer #pragma once over guard macros * Drop redundant #includes * Fix order to ensure that necessary macros are defined when we condition on them - - - - - 4054f0e5 by Ömer Sinan Ağacan at 2019-10-26T19:54:16-04:00 Remove redundant -fno-cse options These were probably added with some GLOBAL_VARs, but those GLOBAL_VARs are now gone. - - - - - c62817f2 by Luke Lau at 2019-10-27T11:35:40-04:00 Fix RankNTypes :ghc-flag: in users guide This fixes a hadrian `build docs` failure - - - - - fc3a5205 by Luke Lau at 2019-10-27T11:35:40-04:00 Remove unused import - - - - - d2520bef by Luke Lau at 2019-10-27T11:35:40-04:00 Fix path to ghc-flags in users guide Hadrian rules It should point to the _build directory, not the source - - - - - 896d470a by Luke Lau at 2019-10-27T11:35:40-04:00 Add back documentation for deprecated -Whi-shadowing This was removed in b538476be3706264620c072e6e436debf9e0d3e4, but without it the compare-flags.py script fails. This adds it back and marks it as deprecated, with a notice that it is slated for removal. - - - - - 7d80f8b5 by Luke Lau at 2019-10-27T11:35:40-04:00 Remove documented flags from expected-undocumented-flags.txt - - - - - fa0d4809 by Ryan Scott at 2019-10-27T11:36:17-04:00 Parenthesize nullary constraint tuples using sigPrec (#17403) We were using `appPrec`, not `sigPrec`, as the precedence when determining whether or not to parenthesize `() :: Constraint`, which lead to the parentheses being omitted in function contexts like `(() :: Constraint) => String`. Easily fixed. Fixes #17403. - - - - - 90d06fd0 by Ben Gamari at 2019-10-27T17:27:17-04:00 hadrian: Silence output from Support SMP check Previously we would allow the output from the check of SMP support introduced by 83655b06e6d3e93b2d15bb0fa250fbb113d7fe68 leak to stdout. Silence this. See #16873. - - - - - 6635a3f6 by Josef Svenningsson at 2019-10-28T09:20:34-04:00 Fix #15344: use fail when desugaring applicative-do Applicative-do has a bug where it fails to use the monadic fail method when desugaring patternmatches which can fail. See #15344. This patch fixes that problem. It required more rewiring than I had expected. Applicative-do happens mostly in the renamer; that's where decisions about scheduling are made. This schedule is then carried through the typechecker and into the desugarer which performs the actual translation. Fixing this bug required sending information about the fail method from the renamer, through the type checker and into the desugarer. Previously, the desugarer didn't have enough information to actually desugar pattern matches correctly. As a side effect, we also fix #16628, where GHC wouldn't catch missing MonadFail instances with -XApplicativeDo. - - - - - cd9b9459 by Ryan Scott at 2019-10-28T09:21:13-04:00 Refactor TcDeriv to validity-check less in anyclass/via deriving (#13154) Due to the way `DerivEnv` is currently structured, there is an invariant that every derived instance must consist of a class applied to a non-empty list of argument types, where the last argument *must* be an application of a type constructor to some arguments. This works for many cases, but there are also some design patterns in standalone `anyclass`/`via` deriving that are made impossible due to enforcing this invariant, as documented in #13154. This fixes #13154 by refactoring `TcDeriv` and friends to perform fewer validity checks when using the `anyclass` or `via` strategies. The highlights are as followed: * Five fields of `DerivEnv` have been factored out into a new `DerivInstTys` data type. These fields only make sense for instances that satisfy the invariant mentioned above, so `DerivInstTys` is now only used in `stock` and `newtype` deriving, but not in other deriving strategies. * There is now a `Note [DerivEnv and DerivSpecMechanism]` describing the bullet point above in more detail, as well as explaining the exact requirements that each deriving strategy imposes. * I've refactored `mkEqnHelp`'s call graph to be slightly less complicated. Instead of the previous `mkDataTypeEqn`/`mkNewTypeEqn` dichotomy, there is now a single entrypoint `mk_eqn`. * Various bits of code were tweaked so as not to use fields that are specific to `DerivInstTys` so that they may be used by all deriving strategies, since not all deriving strategies use `DerivInstTys`. - - - - - e0e04856 by Alan Zimmerman at 2019-10-28T09:21:58-04:00 Attach API Annotations for {-# SOURCE #-} import pragma Attach the API annotations for the start and end locations of the {-# SOURCE #-} pragma in an ImportDecl. Closes #17388 - - - - - e951f219 by Sebastian Graf at 2019-10-28T09:22:35-04:00 Use FlexibleInstances for `Outputable (* p)` instead of match-all instances with equality constraints In #17304, Richard and Simon dicovered that using `-XFlexibleInstances` for `Outputable` instances of AST data types means users can provide orphan `Outputable` instances for passes other than `GhcPass`. Type inference doesn't currently to suffer, and Richard gave an example in #17304 that shows how rare a case would be where the slightly worse type inference would matter. So I went ahead with the refactoring, attempting to fix #17304. - - - - - ad1fe274 by Simon Peyton Jones at 2019-10-28T09:23:14-04:00 Better arity for join points A join point was getting too large an arity, leading to #17294. I've tightened up the invariant: see CoreSyn, Note [Invariants on join points], invariant 2b - - - - - fb4f245c by Takenobu Tani at 2019-10-29T03:45:02-04:00 users-guide: Fix :since: for -xn flag [skip ci] - - - - - 35abbfee by Takenobu Tani at 2019-10-29T03:45:41-04:00 users-guide: Add some new features and fix warnings for GHC 8.10 This updates the following: * Add description for ImportQualifiedPost extension * Add description for ghci command name resolution * Fix markdown warnings [skip ci] - - - - - 57dc1565 by Sylvain Henry at 2019-10-29T03:46:22-04:00 Use `not#` primitive to implement Word's complement - - - - - 28e52732 by Ben Gamari at 2019-10-29T03:46:59-04:00 linters: Add mode to lint given set of files This makes testing much easier. - - - - - db43b3b3 by Ben Gamari at 2019-10-29T03:46:59-04:00 linters: Add linter to catch unquoted use of $(TEST_HC) This is a common bug that creeps into Makefiles (e.g. see T12674). - - - - - ebee0d6b by Ben Gamari at 2019-10-29T03:46:59-04:00 testsuite: Fix quoting of $(TEST_HC) in T12674 I have no idea how this went unnoticed until now. - - - - - 3bd3456f by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 Refactor HscRecomp constructors: Make it evident in the constructors that the final interface is only available when HscStatus is not HscRecomp. (When HscStatus == HscRecomp we need to finish the compilation to get the final interface) `Maybe ModIface` return value of hscIncrementalCompile and the partial `expectIface` function are removed. - - - - - bbdd54aa by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 Return ModIface in compilation pipeline, remove IORef hack for generating ModIfaces The compilation phases now optionally return ModIface (for phases that generate an interface, currently only HscOut when (re)compiling a file). The value is then used by compileOne' to return the generated interface with HomeModInfo (which is then used by the batch mode compiler when building rest of the tree). hscIncrementalMode also returns a DynFlags with plugin info, to be used in the rest of the pipeline. Unfortunately this introduces a (perhaps less bad) hack in place of the previous IORef: we now record the DynFlags used to generate the partial infterface in HscRecomp and use the same DynFlags when generating the full interface. I spent almost three days trying to understand what's changing in DynFlags that causes a backpack test to fail, but I couldn't figure it out. There's a FIXME added next to the field so hopefully someone who understands this better than I do will fix it leter. - - - - - a56433a9 by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 Remove unused DynFlags arg of lookupIfaceByModule - - - - - dcd40c71 by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 HscMain: Move a comment closer to the relevant site - - - - - 593f6543 by Ömer Sinan Ağacan at 2019-10-29T03:47:44-04:00 MkIface: Remove redundant parameter and outdated comments from addFingerprints - - - - - f868e1fe by Ben Gamari at 2019-10-29T03:48:20-04:00 gitlab-ci: Use Hadrian for unregisterised job - - - - - 7b2ecbc0 by Ben Gamari at 2019-10-29T03:48:20-04:00 gitlab-ci: Factor out Linux Hadrian validation logic - - - - - 8e5de15d by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Define USE_LIBFFI_FOR_ADJUSTORS when necessary - - - - - 6a090270 by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Define NOSMP when building rts unregisterised It seems that NOSMP was previously only defined when compiling the compiler, not the RTS. Fix this. In addition do some spring-cleaning and make the logic match that of the Make build system. - - - - - b741d19d by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Shuffle around RTS build flags Some of these flags wanted to be passed to .cmm builds as well as C builds. - - - - - d7cedd9d by Ben Gamari at 2019-10-29T03:48:20-04:00 hadrian: Drop -Werror=unused-but-set-variable from GHC flags Previously `hadrian` would pass `-optc-Werror=unused-but-set-variable` to all GHC invocations. This was a difference from the make build system and cause the unregisterised build to fail as the C that GHC produces contains many unused functions. Drop it from the GHC flags. Note, however, that the flag is still present in `Settings.Builders.Common.cWarnings` and therefore will still be applied during compilation of C sources. - - - - - 7d3a15c7 by Ben Gamari at 2019-10-29T03:48:55-04:00 base: Fix open-file locking The OFD locking path introduced in 3b784d440d4b01b4c549df7c9a3ed2058edfc780 due to #13945 appears to have never actually worked but we never noticed due to an oversight in the autoconf check. Fix it. Thanks to Oleg Grenrus for noticing this. - - - - - 78b70e63 by Ben Gamari at 2019-10-29T03:48:55-04:00 base: Split up file locking implementation This makes the CPP significantly easier to follow. - - - - - 63977398 by Ben Gamari at 2019-10-29T03:49:31-04:00 Don't substitute GccVersion variable Not only is it now unused but we generally can't assume that we are compiling with GCC, so it really shouldn't be used. - - - - - 72f7ac9a by Ben Gamari at 2019-10-29T03:50:06-04:00 Revert "Replace freebsd-gnueabihf with freebsd" This reverts commit aa31ceaf7568802590f73a740ffbc8b800096342 as suggested in #17392. - - - - - 3c0372d6 by Ben Gamari at 2019-10-29T20:31:36-04:00 distrib: Fix binary distribution installation This had silently regressed due to 81860281 and the variable renaming performed in b55ee979, as noted in #17374. - - - - - a7f423ee by Ben Gamari at 2019-10-29T20:31:36-04:00 gitlab-ci: Use pxz to compress binary distributions - - - - - db602643 by Ben Gamari at 2019-10-29T20:31:36-04:00 Don't include settings file in binary distribution The configuration in the installation environment (as determined by `autoconf`) may differ from the build environment and therefore we need to be sure to rebuild the settings file. Fixes #17374. - - - - - 260e2379 by Ben Gamari at 2019-10-29T20:31:36-04:00 gitlab-ci: Fix binary distribution testing - - - - - 01ef3e1f by Ömer Sinan Ağacan at 2019-10-29T20:32:18-04:00 Interpreter: initialize arity fields of AP_NOUPDs AP_NOUPD entry code doesn't use the arity field, but not initializing this field confuses printers/debuggers, and also makes testing harder as the field's value changes randomly. - - - - - 93ff9197 by Ben Gamari at 2019-10-30T07:36:49-04:00 rts: More aarch64 header fixes - - - - - 3e7569bc by Vladislav Zavialov at 2019-10-30T07:36:50-04:00 Whitespace forward compatibility for proposal #229 GHC Proposal #229 changes the lexical rules of Haskell, which may require slight whitespace adjustments in certain cases. This patch changes formatting in a few places in GHC and its testsuite in a way that enables it to compile under the proposed rules. - - - - - 4898df1c by Ben Gamari at 2019-10-30T18:15:52-04:00 gitlab-ci: Fix the ARMv7 triple Previously we were configuring the ARMv7 builds with a host/target triple of arm-linux-gnueabihf, which caused us to target ARMv6 and consequently rely on the old CP15 memory barrier implementation. This barrier has to be emulated on ARMv8 machines which is glacially slow. Hopefully this should fix the ARMv7 builds which currently consistently time out. - - - - - 337e9b5a by Ömer Sinan Ağacan at 2019-10-31T19:01:54-04:00 Remove redundant 0s in ghc-heap pointer strings Before: 0x0000004200c86888 After: 0x42000224f8 This is more concise and consistent with the RTS's printer (which uses %p formatter, and at least on Linux gcc prints the short form) and gdb's pointer formatter. - - - - - 97b6f7a3 by Ben Gamari at 2019-10-31T19:02:32-04:00 base: Clamp IO operation size to 2GB on Darwin As reported in #17414, Darwin throws EINVAL in response to large writes. - - - - - a9743eb7 by Ben Gamari at 2019-10-31T19:02:32-04:00 testsuite: Add test for #17414 - - - - - 73d6e508 by Ben Gamari at 2019-10-31T19:03:10-04:00 base: Various haddock fixes Just a few things I found while looking at #17383. - - - - - dc487642 by taylorfausak at 2019-11-01T04:54:47-04:00 Implement `round` for `Ratio` that doesn't explode with `Natural`s - - - - - 3932fb97 by taylorfausak at 2019-11-01T04:54:47-04:00 Fix rounding around 0 - - - - - baf47ff8 by taylorfausak at 2019-11-01T04:54:47-04:00 Add tests for rounding ratios - - - - - 214d8122 by taylorfausak at 2019-11-01T04:54:47-04:00 Fix running of ratio test case - - - - - 70b62c97 by Ben Gamari at 2019-11-01T04:55:24-04:00 mmap: Factor out protection flags - - - - - c6759080 by Ben Gamari at 2019-11-01T04:55:24-04:00 rts: Make m32 allocator per-ObjectCode MacOS Catalina is finally going to force our hand in forbidden writable exeutable mappings. Unfortunately, this is quite incompatible with the current global m32 allocator, which mixes symbols from various objects in a single page. The problem here is that some of these symbols may not yet be resolved (e.g. had relocations performed) as this happens lazily (and therefore we can't yet make the section read-only and therefore executable). The easiest way around this is to simply create one m32 allocator per ObjectCode. This may slightly increase fragmentation for short-running programs but I suspect will actually improve fragmentation for programs doing lots of loading/unloading since we can always free all of the pages allocated to an object when it is unloaded (although this ability will only be implemented in a later patch). - - - - - 35c99e72 by Simon Peyton Jones at 2019-11-01T04:56:02-04:00 Makes Lint less chatty: I found in #17415 that Lint was printing out truly gigantic warnings, unmanageably huge, with repeated copies of the same thing. This patch makes Lint less chatty, especially for warnings: * For **warnings**, I don't print details of the location, unless you add `-dppr-debug`. * For **errors**, I still print all the info. They are fatal and stop exection, whereas warnings appear repeatedly. * I've made much less use of `AnExpr` in `LintLocInfo`; the expression can be gigantic. - - - - - d2471964 by Simon Peyton Jones at 2019-11-01T04:56:38-04:00 Add another test for #17267 This one came in a comment from James Payor - - - - - 1e2e82aa by Simon Peyton Jones at 2019-11-01T04:57:15-04:00 Fix a bad error in tcMatchTy This patch fixes #17395, a very subtle and hard-to-trigger bug in tcMatchTy. It's all explained in Note [Matching in the presence of casts (2)] I have not added a regression test because it is very hard to trigger it, until we have the upcoming mkAppTyM patch, after which lacking this patch means you can't even compile the libraries. - - - - - 51067194 by Ben Gamari at 2019-11-01T15:48:37-04:00 base: Ensure that failIO isn't SOURCE imported failIO has useful information in its demand signature (specifically that it bottoms) which is hidden if it is SOURCE imported, as noted in #16588. Rejigger things such that we don't SOURCE import it. Metric Increase: T13701 - - - - - c751082c by Ben Gamari at 2019-11-01T15:48:37-04:00 testsuite: Make ExplicitForAllRules1 more robust Previously the test relied on `id` not inlining. Fix this. - - - - - dab12c87 by Ben Gamari at 2019-11-01T15:48:37-04:00 Describe optimisation of demand analysis of noinline As described in #16588. - - - - - c9236384 by Adam Sandberg Eriksson at 2019-11-01T15:49:16-04:00 template-haskell: require at least 1 GADT constructor name (#17379) - - - - - a4ce26e0 by Ben Gamari at 2019-11-01T15:49:53-04:00 hadrian: Make runtest invocation consistency with Make Use True/False instead of 0/1. This shouldn't be a functional change but we should be consistent. - - - - - cabafe34 by Ben Gamari at 2019-11-01T15:50:29-04:00 testsuite: Add test for #17423 - - - - - 4a6d3d68 by Simon Peyton Jones at 2019-11-01T23:11:37-04:00 Make CSE delay inlining less CSE delays inlining a little bit, to avoid losing vital specialisations; see Note [Delay inlining after CSE] in CSE. But it was being over-enthusiastic. This patch makes the delay only apply to Ids with specialisation rules, which avoids unnecessary delay (#17409). - - - - - 01006bc7 by Niklas Hambüchen at 2019-11-01T23:12:17-04:00 doc: Fix backticks - - - - - 9980fb58 by Niklas Hambüchen at 2019-11-01T23:12:17-04:00 Add +RTS --disable-delayed-os-memory-return. Fixes #17411. Sets `MiscFlags.disableDelayedOsMemoryReturn`. See the added `Note [MADV_FREE and MADV_DONTNEED]` for details. - - - - - 182b1199 by Sebastian Graf at 2019-11-02T20:16:33-04:00 Separate `LPat` from `Pat` on the type-level Since the Trees That Grow effort started, we had `type LPat = Pat`. This is so that `SrcLoc`s would only be annotated in GHC's AST, which is the reason why all GHC passes use the extension constructor `XPat` to attach source locations. See #15495 for the design discussion behind that. But now suddenly there are `XPat`s everywhere! There are several functions which dont't cope with `XPat`s by either crashing (`hsPatType`) or simply returning incorrect results (`collectEvVarsPat`). This issue was raised in #17330. I also came up with a rather clean and type-safe solution to the problem: We define ```haskell type family XRec p (f :: * -> *) = r | r -> p f type instance XRec (GhcPass p) f = Located (f (GhcPass p)) type instance XRec TH f = f p type LPat p = XRec p Pat ``` This is a rather modular embedding of the old "ping-pong" style, while we only pay for the `Located` wrapper within GHC. No ping-ponging in a potential Template Haskell AST, for example. Yet, we miss no case where we should've handled a `SrcLoc`: `hsPatType` and `collectEvVarsPat` are not callable at an `LPat`. Also, this gets rid of one indirection in `Located` variants: Previously, we'd have to go through `XPat` and `Located` to get from `LPat` to the wrapped `Pat`. Now it's just `Located` again. Thus we fix #17330. - - - - - 3c916162 by Richard Eisenberg at 2019-11-02T20:17:13-04:00 Update Note references -- comments only Follow-on from !2041. - - - - - 3b65655c by Ben Gamari at 2019-11-04T03:40:31-05:00 SysTools: Only apply Windows-specific workaround on Windows Issue #1110 was apparently due to a bug in Vista which prevented GCC from finding its binaries unless we explicitly added it to PATH. However, this workaround was incorrectly applied on non-Windows platforms as well, resulting in ill-formed PATHs (#17266). Fixes #17266. - - - - - 5d4f16ee by Leif Metcalf at 2019-11-04T03:41:09-05:00 Rephrase note on full-laziness - - - - - 120f2e53 by Ben Gamari at 2019-11-04T03:41:44-05:00 rts/linker: Ensure that code isn't writable For many years the linker would simply map all of its memory with PROT_READ|PROT_WRITE|PROT_EXEC. However operating systems have been becoming increasingly reluctant to accept this practice (e.g. #17353 and #12657) and for good reason: writable code is ripe for exploitation. Consequently mmapForLinker now maps its memory with PROT_READ|PROT_WRITE. After the linker has finished filling/relocating the mapping it must then call mmapForLinkerMarkExecutable on the sections of the mapping which contain executable code. Moreover, to make all of this possible it was necessary to redesign the m32 allocator. First, we gave (in an earlier commit) each ObjectCode its own m32_allocator. This was necessary since code loading and symbol resolution/relocation are currently interleaved, meaning that it is not possible to enforce W^X when symbols from different objects reside in the same page. We then redesigned the m32 allocator to take advantage of the fact that all of the pages allocated with the allocator die at the same time (namely, when the owning ObjectCode is unloaded). This makes a number of things simpler (e.g. no more page reference counting; the interface provided by the allocator for freeing is simpler). See Note [M32 Allocator] for details. - - - - - 7c28087a by Takenobu Tani at 2019-11-05T02:45:31-05:00 users-guide: Improve documentaion of CPP extension Currently, the description of CPP extension is given in the section of command-line options. Therefore, it is a little difficult to understand that it is a language extension. This commit explicitly adds a description for it. [skip ci] - - - - - d57059f7 by Ben Gamari at 2019-11-05T02:46:10-05:00 rts: Add missing const in HEAP_ALLOCED_GC This was previously unnoticed as this code-path is hit on very few platforms (e.g. OpenBSD). - - - - - 487ede42 by Peter Trommler at 2019-11-05T02:46:48-05:00 testsuite: skip test requiring RTS linker on PowerPC The RTS linker is not available on 64-bit PowerPC. Instead of marking tests that require the RTS linker as broken on PowerPC 64-bit skip the respective tests on all platforms where the RTS linker or a statically linked external interpreter is not available. Fixes #11259 - - - - - 1593debf by Sebastian Graf at 2019-11-05T11:38:30-05:00 Check EmptyCase by simply adding a non-void constraint We can handle non-void constraints since !1733, so we can now express the strictness of `-XEmptyCase` just by adding a non-void constraint to the initial Uncovered set. For `case x of {}` we thus check that the Uncovered set `{ x | x /~ ⊥ }` is non-empty. This is conceptually simpler than the plan outlined in #17376, because it talks to the oracle directly. In order for this patch to pass the testsuite, I had to fix handling of newtypes in the pattern-match checker (#17248). Since we use a different code path (well, the main code path) for `-XEmptyCase` now, we apparently also handle #13717 correctly. There's also some dead code that we can get rid off now. `provideEvidence` has been updated to provide output more in line with the old logic, which used `inhabitationCandidates` under the hood. A consequence of the shift away from the `UncoveredPatterns` type is that we don't report reduced type families for empty case matches, because the pretty printer is pure and only knows the match variable's type. Fixes #13717, #17248, #17386 - - - - - e6ffe148 by Ömer Sinan Ağacan at 2019-11-05T11:39:13-05:00 TidyPgm: replace an explicit loop with mapAccumL - - - - - b7460492 by Ömer Sinan Ağacan at 2019-11-05T11:39:13-05:00 CoreTidy: hide tidyRule - - - - - f9978f53 by Stefan Schulze Frielinghaus at 2019-11-05T11:39:51-05:00 Hadrian: enable interpreter for s390x - - - - - 3ce18700 by Ben Gamari at 2019-11-06T08:05:57-05:00 rts: Drop redundant flags for libffi These are now handled in the cabal file's include-dirs field. - - - - - ce9e2a1a by Ben Gamari at 2019-11-06T08:05:57-05:00 configure: Add --with-libdw-{includes,libraries} flags Fixing #17255. - - - - - 97f9674b by Takenobu Tani at 2019-11-06T08:06:37-05:00 configure: Add checking python3-sphinx This checks the configuration about python3-sphinx. We need python3-sphinx instead of python2-sphinx to build documentation. The approach is as follows: * Check python3 version with custom `conf.py` invoked from sphinx-build` executable * Place custom `conf.py` into new `utils/check-sphinx` directory If sphinx is for python2 not python3, it's treated as config ERROR instead of WARN. See also #17346 and #17356. - - - - - b4fb2328 by Dan Brooks at 2019-11-06T08:07:15-05:00 Adding examples to Semigroup/monoid - - - - - 708c60aa by Ryan Scott at 2019-11-07T08:39:36-05:00 Clean up TH's treatment of unary tuples (or, #16881 part two) !1906 left some loose ends in regards to Template Haskell's treatment of unary tuples. This patch ends to tie up those loose ends: * In addition to having `TupleT 1` produce unary tuples, `TupE [exp]` and `TupP [pat]` also now produce unary tuples. * I have added various special cases in GHC's pretty-printers to ensure that explicit 1-tuples are printed using the `Unit` type. See `testsuite/tests/th/T17380`. * The GHC 8.10.1 release notes entry has been tidied up a little. Fixes #16881. Fixes #17371. Fixes #17380. - - - - - a424229d by Stefan Schulze Frielinghaus at 2019-11-07T08:40:13-05:00 For s390x issue a warning if LLVM 9 or older is used For s390x the GHC calling convention is only supported since LLVM version 10. Issue a warning in case an older version of LLVM is used. - - - - - 55bc3787 by Ben Gamari at 2019-11-07T08:40:50-05:00 FlagChecker: Add ticky flags to hashed flags These affect output and therefore should be part of the flag hash. - - - - - fa0b1b4b by Stefan Schulze Frielinghaus at 2019-11-07T08:41:33-05:00 Bump libffi-tarballs submodule - - - - - a9566632 by Takenobu Tani at 2019-11-07T08:42:15-05:00 configure: Modify ERROR to WARN for sphinx's python check If sphinx's python version check failed, many people prefer to build without documents instead of stopping on the error. So this commit fixes the following: * Modify AC_MSG_ERROR to AC_MSG_WARN * Add clearing of SPHINXBUILD variable when check fails See also !2016. - - - - - d0ef8312 by Alp Mestanogullari at 2019-11-07T21:24:59-05:00 hadrian: fix support for the recording of perf test results Before this patch, Hadrian didn't care about the TEST_ENV and METRICS_FILE environment variables, that the performance testing infrastructure uses to record perf tests results from CI jobs. It now looks them up right before running the testsuite driver, and passes suitable --test-env/--metrics-file arguments when these environment variables are set. - - - - - 601e554c by Ben Gamari at 2019-11-07T21:25:36-05:00 Bump the process submodule This should fix the #17108 and #17249 with the fix from https://github.com/haskell/process/pull/159. - - - - - 6b7d7e1c by Ben Gamari at 2019-11-07T21:25:36-05:00 Bump hsc2hs submodule - - - - - b1c158c9 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts: Fix m32 allocator build on Windows An inconsistency in the name of m32_allocator_flush caused the build to fail with a missing prototype error. - - - - - ae431cf4 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts: Ensure that Rts.h is always included first In general this is the convention that we use in the RTS. On Windows things actually fail if we break it. For instance, you see things like: includes\stg\Types.h:26:9: error: warning: #warning "Mismatch between __USE_MINGW_ANSI_STDIO definitions. If using Rts.h make sure it is the first header included." [-Wcpp] - - - - - 0d141d28 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts: Remove undesireable inline specifier I have no idea why I marked this as inline originally but clearly it shouldn't be inlined. - - - - - 870376f9 by Ben Gamari at 2019-11-07T21:25:36-05:00 base: Add missing imports in Windows locking implementation - - - - - 23994738 by Ben Gamari at 2019-11-07T21:25:36-05:00 rts/NonMoving: Fix various Windows build issues The Windows build seems to be stricter about not providing threading primitives in the non-threaded RTS. - - - - - a3ce52fd by Ben Gamari at 2019-11-07T21:25:36-05:00 users_guide: Set flags list file encoding Otherwise this fails on Windows. - - - - - 9db2e905 by Stefan Schulze Frielinghaus at 2019-11-08T05:36:54-05:00 Testsuite: Introduce req_rts_linker Some tests depend on the RTS linker. Introduce a modifier to skip such tests, in case the RTS linker is not available. - - - - - a4631335 by Szymon Nowicki-Korgol at 2019-11-08T05:37:34-05:00 Set correct length of DWARF .debug_aranges section (fixes #17428) - - - - - 3db2ab30 by Ben Gamari at 2019-11-08T05:38:11-05:00 hadrian: Add enableTickyGhc helper This took a bit of trial-and-error to get working so it seems worth having in the tree. - - - - - 5c87ebd7 by Ben Gamari at 2019-11-08T12:09:22-05:00 SetLevels: Don't set context level when floating cases When floating a single-alternative case we previously would set the context level to the level where we were floating the case. However, this is wrong as we are only moving the case and its binders. This resulted in #16978, where the disrepancy caused us to unnecessarily abstract over some free variables of the case body, resulting in shadowing and consequently Core Lint failures. (cherry picked from commit a2a0e6f3bb2d02a9347dec4c7c4f6d4480bc2421) - - - - - 43623b09 by Ben Gamari at 2019-11-08T12:10:01-05:00 testsuite: Run tests in nonmoving_thr in speed==slow - - - - - 6e4656cc by Ben Gamari at 2019-11-08T12:10:01-05:00 rts/nonmoving: Catch failure of createOSThread - - - - - 2e4fc04b by Ben Gamari at 2019-11-08T12:10:01-05:00 Bump unix submodule Marks executeFile001 as broken in all concurrent ways. - - - - - 8a10f9fb by Ben Gamari at 2019-11-09T18:03:01-05:00 template-haskell: Document assembler foreign file support See #16180. - - - - - 5ad3cb53 by Ben Gamari at 2019-11-09T18:03:01-05:00 template-haskell: Fix TBAs in changelog - - - - - 4a75a832 by Ben Gamari at 2019-11-09T18:03:01-05:00 base: Fix TBA in changelog - - - - - d7de0d81 by Ryan Scott at 2019-11-09T18:03:02-05:00 template-haskell: Fix italics in changelog [ci-skip] - - - - - 0fb246c3 by Ben Gamari at 2019-11-09T18:03:37-05:00 testsuite: Fix Windows cleanup path This was a regression introduced with the Path refactoring. - - - - - 925fbdbb by Ben Gamari at 2019-11-09T18:03:37-05:00 testsuite: Skip T16916 on Windows The event manager is not supported on Windows. - - - - - 7c2ce0a0 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Skip T14931 on Windows This test uses -dynamic-too, which is not supported on Windows. - - - - - 7c63edb4 by Ben Gamari at 2019-11-09T18:03:38-05:00 gitlab-ci: Don't allow Windows make job to fail While linking is still slow (#16084) all of the correctness issues which were preventing us from being able to enforce testsuite-green on Windows are now resolved. - - - - - a50ecda6 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Fix header #include order on Windows <Rts.h> must always come first. - - - - - dcb23ec9 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T13676 as broken on Darwin and Windows Due to #17447. - - - - - 411ba7ba by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T11627b as fragile It was previously marked as broken due to #12236 however it passes for me locally while failing on CI. - - - - - c1f1f3f9 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T16219 as unbroken This was previously broken due to #16386 yet it passes for me locally. - - - - - 1f871e70 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Remove redundant cleaning logic from T16511 The GHCi script for T16511 had some `rm` commands to clean up output from previous runs. This should be harmless since stderr was redirected to /dev/null; however, it seems that this redirection doesn't work on Windows (perhaps because GHCi uses `cmd` to execute the command-line; I'm not sure). I tried to fix it but was unable to find a sensible solution. Regardless, the cleaning logic is quite redundant now that we run each test in a hermetic environment. Let's just remove it. - - - - - 4d523cb1 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T17414 as fragile on Windows This consistently times out on Windows as described in #17453. I have tried increasing the timeout multiplier to two yet it stills fails. Disabling until we have time to investigate. - - - - - f73fbd2d by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Ignore stderr in PartialDownsweep As described in #17449, PartialDownsweep is currently fragile due to its dependence on the error messages produced by the C preprocessor. To eliminate this dependence we simply ignore stderr output, instead relying on the fact that the test will exit with a non-zero exit code on failure. Fixes #17449. - - - - - a9b14790 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Fix putStrLn in saks028 Bizarrely, `saks028` previously failed reliably, but only on Windows (#17450). The test would exit with a zero exit code but simply didn't emit the expected text to stderr. I believe this was due to the fact that the test used `putStrLn`, resulting in the output ending up on stdout. This worked on other platforms since (apparently) we redirect stdout to stderr when evaluating splices. However, on Windows it seems that the redirected output wasn't flushed as it was on other platforms. Anyways, it seems like the right thing to do here is to be explicit about our desire for the output to end up on stderr. Closes #17450. - - - - - b62ca659 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Drop T7995 This test is quite sensitive to the build configuration as it requires that ghc have unfoldings, which isn't true in the quick build flavours. I considered various options to make the test more robust but none of them seemed particularly appealing. Moreover, Simon PJ was a bit skeptical of the value of the test to begin with and I strongly suspect that any regression in #7995 would be accompanied by failures in our other compiler performance tests. Closes #17399. - - - - - 011f3121 by Ben Gamari at 2019-11-09T18:03:38-05:00 testsuite: Mark T16219 as fragile on Windows As noted in #17452, this test produces very long file paths which exceed the Windows MAX_PATH limitation. Mark the test as fragile for not until we can come up with a better solution. - - - - - 1f98e47d by Simon Peyton Jones at 2019-11-09T18:04:14-05:00 Use the right type in :force A missing prime meant that we were considering the wrong type in the GHCi debugger, when doing :force on multiple arguments (issue #17431). The fix is trivial. - - - - - 1f911de4 by Brian Wignall at 2019-11-09T18:04:57-05:00 Add IsList instance for ZipList (closes #17433) - - - - - e3672f40 by Brian Wignall at 2019-11-09T18:04:57-05:00 Incorporate MR review suggestions; add change in changelog - - - - - 3957bdf2 by Brian Wignall at 2019-11-09T18:04:57-05:00 Fix incorrect plurals - - - - - 6f4c1250 by Alina Banerjee at 2019-11-10T01:06:12-05:00 Improve SPECIALIZE pragma error messages (Fixes #12126) - - - - - fa25c8c4 by Richard Eisenberg at 2019-11-10T01:06:48-05:00 Update release notes about #16512 / #17405. - - - - - 55ca1085 by Richard Eisenberg at 2019-11-10T01:06:48-05:00 Fix #17405 by not checking imported equations Previously, we checked all imported type family equations for injectivity. This is very silly. Now, we check only for conflicts. Before I could even imagine doing the fix, I needed to untangle several functions that were (in my opinion) overly complicated. It's still not quite as perfect as I'd like, but it's good enough for now. Test case: typecheck/should_compile/T17405 - - - - - a9467f4f by Ben Gamari at 2019-11-10T21:06:33-05:00 testsuite: Mark tests fragile in threaded2 as fragile in all concurrent ways - - - - - 3e07ea8d by Ben Gamari at 2019-11-10T21:10:30-05:00 testsuite: Use small allocation area when measuring residency As suggested in #17387; this helps reduce the variance in our residency sampling. Metric Increase: T10370 T3586 lazy-bs-alloc Metric Decrease 'compile_time/peak_megabytes_allocated': T1969 Metric Decrease 'runtime/bytes allocated': space_leak_001 Metric Increase 'compile_time/bytes allocated': T1969 Metric Increase 'runtime/peak_megabytes_allocated': space_leak_001 Metric Decrease: T3064 T9675 - - - - - 049d9ae0 by Ben Gamari at 2019-11-10T21:10:30-05:00 testsuite: Don't check_stats at runtime if not requested Previously we would call check_stats to check the runtime metrics even if the test definition hadn't requested it. This would result in an error since the .stats file doesn't exist. - - - - - 64433428 by Alp Mestanogullari at 2019-11-11T08:49:01-05:00 hadrian: export METRICS_FILE to make it accessible to perf notes script This addresses #17456 and also fixes the --metrics-file argument that Hadrian passes to the testsuite driver. - - - - - 06640394 by Ben Gamari at 2019-11-11T08:50:45-05:00 testsuite: Disable T4334 in nonmoving_thr way - - - - - f8ec32d7 by Alp Mestanogullari at 2019-11-11T11:36:44-05:00 ci: push perf test metrics even when the testsuite doesn't pass The corresponding commit might introduce a regression on a perf test, in which case we certainly want to record it. The testsuite might also fail because of a test unrelated to performance, in which case we want to record that the perf test results were good. Either way, we likely want to record them under all circumstances but we don't without this patch. Metric Decrease: T3586 Metric Increase: lazy-bs-alloc - - - - - 643d42fc by Alp Mestanogullari at 2019-11-12T18:40:19-05:00 testsuite: don't collect compiler stats in collect_runtime_residency We instead want to collect the runtime stats (with collect_stats, instead of collect_compiler_stats). This should fix a number of perf tests failures we have been seeing, where we suddenly started measuring metrics we didn't intend to measure, which tend to fall outside of the acceptance window. Metric Decrease: lazy-bs-alloc T3586 Metric Increase: space_leak_001 T4801 T5835 T12791 - - - - - 535d0edc by Ömer Sinan Ağacan at 2019-11-13T07:06:12-05:00 Document CmmTopInfo type [ci skip] - - - - - 2d4f9ad8 by Ben Gamari at 2019-11-13T07:06:49-05:00 Ensure that coreView/tcView are able to inline Previously an import cycle between Type and TyCoRep meant that several functions in TyCoRep ended up SOURCE import coreView. This is quite unfortunate as coreView is intended to be fused into a larger pattern match and not incur an extra call. Fix this with a bit of restructuring: * Move the functions in `TyCoRep` which depend upon things in `Type` into `Type` * Fold contents of `Kind` into `Type` and turn `Kind` into a simple wrapper re-exporting kind-ish things from `Type` * Clean up the redundant imports that popped up as a result Closes #17441. Metric Decrease: T4334 - - - - - b795637f by Alp Mestanogullari at 2019-11-13T07:07:28-05:00 hadrian: fix Windows CI script By only using 'export' from within bash commands. - - - - - 6885e22c by Ben Gamari at 2019-11-13T07:08:03-05:00 testsuite: Add test for #17458 As noted in #17458, QuantifiedConstraints and UndecideableInstances could previously be used to write programs which can loop at runtime. This was fixed in !1870. - - - - - b4b19d89 by Ben Gamari at 2019-11-13T07:08:03-05:00 users guide: Fix broken link - - - - - 9a939a6c by Ryan Scott at 2019-11-13T07:08:40-05:00 Print name prefixly in the Outputable instance for StandaloneKindSig Issue #17461 was occurring because the `Outputable` instance for standalone kind signatures was simply calling `ppr` on the name in the kind signature, which does not add parentheses to infix names. The solution is simple: use `pprPrefixOcc` instead. Fixes #17461. - - - - - a06cfb59 by Ömer Sinan Ağacan at 2019-11-13T07:09:18-05:00 Only pass mod_location with HscRecomp instead of the entire ModSummary HscRecomp users only need the ModLocation of the module being compiled, so only pass that to users instead of the entire ModSummary Metric Decrease: T4801 - - - - - dd49b3f0 by Ben Gamari at 2019-11-13T17:01:21-05:00 Bump Haskeline and add exceptions as boot library Haskeline now depends upon exceptions. See #16752. - - - - - b06b1858 by Ben Gamari at 2019-11-14T11:30:20-05:00 base: Bump version to 4.14.0.0 Metric Increase: T4801 - - - - - 6ab80439 by Ben Gamari at 2019-11-14T23:05:30-05:00 gitlab-ci: Allow Windows to fail again - - - - - 46afc380 by Ben Gamari at 2019-11-15T09:45:36-05:00 gitlab-ci: Install process to global pkgdb before starting build This is an attempt to mitigate #17480 by ensuring that a functional version of the process library is available before attempting the build. - - - - - 8c5cb806 by Ben Gamari at 2019-11-15T10:45:55-05:00 Bump supported LLVM version to 9.0 - - - - - 8e5851f0 by Ben Gamari at 2019-11-15T10:45:55-05:00 llvm-targets: Update with Clang 9 - - - - - f3ffec27 by Ben Gamari at 2019-11-15T11:54:26-05:00 testsuite: Increase acceptance window of T4801 This statistic is rather unstable. Hopefully fixes #17475. - - - - - c2991f16 by Ben Gamari at 2019-11-15T11:56:10-05:00 users-guide: Drop 8.6.1 release notes - - - - - e8da1354 by Ben Gamari at 2019-11-17T06:48:16-05:00 gitlab-ci: Fix submodule linter We ran it against the .git directory despite the fact that the linter wants to be run against the repository. - - - - - 13290f91 by Ben Gamari at 2019-11-17T06:48:16-05:00 Bump version to 8.10.0 Bumps haddock submodule. - - - - - fa98f823 by Ben Gamari at 2019-11-17T06:48:16-05:00 testsuite: Don't collect residency for T4801 I previously increased the size of the acceptance window from 2% to 5% but this still isn't enough. Regardless, measuring bytes allocated should be sufficient to catch any regressions. - - - - - 002b2842 by Ivan Kasatenko at 2019-11-17T06:49:22-05:00 Make test 16916 more stable across runs - - - - - ca89dd3b by Ben Gamari at 2019-11-17T06:58:17-05:00 users-guide: Address #17329 Adopts the language suggested by @JakobBruenker. - - - - - 2f5ed225 by Ben Gamari at 2019-11-17T07:16:32-05:00 exceptions: Bump submodule back to master The previous commit hasn't made it to master yet. - - - - - 34515e7c by nineonine at 2019-11-17T13:33:22-08:00 Fix random typos [skip ci] - - - - - 4a37a29b by Mario Blažević at 2019-11-17T17:26:24-05:00 Fixed issue #17435, missing Data instances - - - - - 97f1bcae by Andreas Klebinger at 2019-11-17T17:26:24-05:00 Turn some comments into GHC.Hs.Utils into haddocks - - - - - cf7f8e5b by Ben Gamari at 2019-11-17T17:26:26-05:00 testsuite: Skip T17414 on Linux It is typical for $TMP to be a small tmpfson Linux. This test will fail in such cases since we must create a file larger than the filesystem. See #17459. - - - - - 88013b78 by nineonine at 2019-11-19T11:53:16-05:00 Optimize MonadUnique instances based on IO (#16843) Metric Decrease: T14683 - - - - - a8adb5b4 by Ben Gamari at 2019-11-19T11:53:55-05:00 desugar: Drop stale Note [Matching seqId] The need for this note vanished in eae703aa60f41fd232be5478e196b661839ec3de. - - - - - 08d595c0 by Ben Gamari at 2019-11-19T11:53:55-05:00 Give seq a more precise type and remove magic `GHC.Prim.seq` previously had the rather plain type: seq :: forall a b. a -> b -> b However, it also had a special typing rule to applications where `b` is not of kind `Type`. Issue #17440 noted that levity polymorphism allows us to rather give it the more precise type: seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b This allows us to remove the special typing rule that we previously required to allow applications on unlifted arguments. T9404 contains a non-Type application of `seq` which should verify that this works as expected. Closes #17440. - - - - - ec8a463d by Viktor Dukhovni at 2019-11-19T11:54:45-05:00 Enable USE_PTHREAD_FOR_ITIMER also on FreeBSD If using a pthread instead of a timer signal is more reliable, and has no known drawbacks, then FreeBSD is also capable of supporting this mode of operation (tested on FreeBSD 12 with GHC 8.8.1, but no reason why it would not also work on FreeBSD 11 or GHC 8.6). Proposed by Kevin Zhang in: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=241849 - - - - - cd40e12a by Ömer Sinan Ağacan at 2019-11-19T11:55:36-05:00 Packages.hs: use O(n*log(n)) ordNub instead of O(n*n) nub As reported in #8173 in some environments package lists can get quite long, so we use more efficient ordNub instead of nub on package lists. - - - - - 2b27cc16 by Ben Gamari at 2019-11-19T11:56:21-05:00 Properly account for libdw paths in make build system Should finally fix #17255. - - - - - 0418c38d by Ben Gamari at 2019-11-19T11:56:58-05:00 rts: Add missing include of SymbolExtras.h This broke the Windows build. - - - - - c819c0e4 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Use correct info table pointer accessor Previously we used INFO_PTR_TO_STRUCT instead of THUNK_INFO_PTR_TO_STRUCT when looking at a thunk. These two happen to be equivalent on 64-bit architectures due to alignment considerations however they are different on 32-bit platforms. This lead to #17487. To fix this we also employ a small optimization: there is only one thunk of type WHITEHOLE (namely stg_WHITEHOLE_info). Consequently, we can just use a plain pointer comparison instead of testing against info->type. - - - - - deed8e31 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Fix incorrect masking in mark queue type test We were using TAG_BITS instead of TAG_MASK. This happened to work on 64-bit platforms where TAG_BITS==3 since we only use tag values 0 and 3. However, this broken on 32-bit platforms where TAG_BITS==2. - - - - - 097f8072 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Rework mark queue representation The previous representation needlessly limited the array length to 16-bits on 32-bit platforms. - - - - - eb7b233a by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Fix handling on large object marking on 32-bit Previously we would reset the pointer pointing to the object to be marked to the beginning of the block when marking a large object. This did no harm on 64-bit but on 32-bit it broke, e.g. `arr020`, since we align pinned ByteArray allocations such that the payload is 8 byte-aligned. This means that the object might not begin at the beginning of the block., - - - - - a7571a74 by Ben Gamari at 2019-11-19T11:57:36-05:00 testsuite: Increase width of stack003 test Previously the returned tuple seemed to fit in registers on amd64. This meant that non-moving collector bug would cause the test to fail on i386 yet not amd64. - - - - - 098d5017 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Drop redundant write barrier on stack underflow Previously we would push stack-carried return values to the new stack on a stack overflow. While the precise reasoning for this barrier is unfortunately lost to history, in hindsight I suspect it was prompted by a missing barrier elsewhere (that has been since fixed). Moreover, there the redundant barrier is actively harmful: the stack may contain non-pointer values; blindly pushing these to the mark queue will result in a crash. This is precisely what happened in the `stack003` test. However, because of a (now fixed) deficiency in the test this crash did not trigger on amd64. - - - - - e57b7cc6 by Roland Zumkeller at 2019-11-19T20:39:19-05:00 Changing Thread IDs from 32 bits to 64 bits. - - - - - d1f3c637 by Roland Zumkeller at 2019-11-19T20:39:19-05:00 Use pointer equality in Eq/Ord for ThreadId Changes (==) to use only pointer equality. This is safe because two threads are the same iff they have the same id. Changes `compare` to check pointer equality first and fall back on ids only in case of inequality. See discussion in #16761. - - - - - ef8a08e0 by Alexey Kuleshevich at 2019-11-19T20:39:20-05:00 hpc: Fix encoding issues. Add test for and fix #17073 * Make sure files are being read/written in UTF-8. Set encoding while writing HTML output. Also set encoding while writing and reading .tix files although we don't yet have a ticket complaining that this poses problems. * Set encoding in html header to utf8 * Upgrade to new version of 'hpc' library and reuse `readFileUtf8` and `writeFileUtf8` functions * Update git submodule for `hpc` * Bump up `hpc` executable version Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - b79e46d6 by Vladislav Zavialov at 2019-11-19T20:39:20-05:00 Strip parentheses in expressions contexts in error messages This makes error messages a tad less noisy. - - - - - 13bbde77 by Ben Gamari at 2019-11-21T13:56:56-05:00 Bump hsc2hs submodule Including Phyx's backport of the process changes fixing #17480. - - - - - d4d10501 by Ben Gamari at 2019-11-23T09:42:38-05:00 Bump hsc2hs submodule again This fixes the Darwin build. - - - - - 889d475b by nineonine at 2019-11-23T18:53:29-05:00 Fix typo in Note reference [skip ci] - - - - - 8a33abfc by Ryan Scott at 2019-11-23T18:54:05-05:00 Target the IsList instance for ZipList at base-4.14.0.0 (#17489) This moves the changelog entry about the instance from `base-4.15.0.0` to `base-4.14.0.0`. This accomplishes part (1) from #17489. [ci skip] - - - - - e43e6ece by Ben Gamari at 2019-11-23T18:54:41-05:00 rts: Expose interface for configuring EventLogWriters This exposes a set of interfaces from the GHC API for configuring EventLogWriters. These can be used by consumers like [ghc-eventlog-socket](https://github.com/bgamari/ghc-eventlog-socket). - - - - - de6bbdf2 by Matheus Magalhães de Alcantara at 2019-11-23T18:55:23-05:00 Take care to not eta-reduce jumps in CorePrep CorePrep already had a check to prevent it from eta-reducing Ids that respond true to hasNoBinding (foreign calls, constructors for unboxed sums and products, and Ids with compulsory unfoldings). It did not, however, consider join points as ids that 'must be saturated'. Checking whether the Id responds True to 'isJoinId' should prevent CorePrep from turning saturated jumps like the following (from #17429) into undersaturated ones: (\ eta_XP -> join { mapped_s1vo _ = lvl_s1vs } in jump mapped_s1vo eta_XP) - - - - - 4a1e7e47 by Matheus Magalhães de Alcantara at 2019-11-23T18:55:23-05:00 Make CorePrep.tryEtaReducePrep and CoreUtils.tryEtaReduce line up Simon PJ says he prefers this fix to #17429 over banning eta-reduction for jumps entirely. Sure enough, this also works. Test case: simplCore/should_compile/T17429.hs - - - - - 15f1dc33 by Ryan Scott at 2019-11-23T18:56:00-05:00 Prevent -optc arguments from being duplicated in reverse order (#17471) This reverts a part of commit 7bc5d6c6578ab9d60a83b81c7cc14819afef32ba that causes all arguments to `-optc` (and `-optcxx`) to be passed twice to the C/C++ compiler, once in reverse order and then again in the correct order. While passing duplicate arguments is usually harmless it can cause breakage in this pattern, which is employed by Hackage libraries in the wild: ``` ghc Foo.hs foo.c -optc-D -optcFOO ``` As `FOO -D -D FOO` will cause compilers to error. Fixes #17471. - - - - - e85c9b22 by Ben Gamari at 2019-11-23T18:56:36-05:00 Bump ghc version to 8.11 - - - - - 0e6c2045 by Ben Gamari at 2019-11-23T18:57:12-05:00 rts: Consolidate spinlock implementation Previously we had two distinct implementations: one with spinlock profiling and another without. This seems like needless duplication. - - - - - cb11fcb5 by Ben Gamari at 2019-11-23T18:57:49-05:00 Packages: Don't use expectJust Throw a slightly more informative error on failure. Motivated by the errors seen in !2160. - - - - - 5747ebe9 by Sebastian Graf at 2019-11-23T18:58:25-05:00 Stricten functions ins GHC.Natural This brings `Natural` on par with `Integer` and fixes #17499. Also does some manual CSE for 0 and 1 literals. - - - - - c14b723f by Ömer Sinan Ağacan at 2019-11-23T18:59:06-05:00 Bump exceptions submodule Adds a few files generated by GHC's configure script to .gitignore - - - - - 7b4c7b75 by Brian Wignall at 2019-11-23T19:04:52-05:00 Fix typos - - - - - 6008206a by Viktor Dukhovni at 2019-11-24T14:33:18-05:00 On FreeBSD 12 sys/sysctl.h requires sys/types.h Else build fails with: In file included from ExecutablePath.hsc:42: /usr/include/sys/sysctl.h:1062:25: error: unknown type name 'u_int'; did you mean 'int'? int sysctl(const int *, u_int, void *, size_t *, const void *, size_t); ^~~~~ int compiling libraries/base/dist-install/build/System/Environment/ExecutablePath_hsc_make.c failed (exit code 1) Perhaps also also other FreeBSD releases, but additional include will no harm even if not needed. - - - - - b694b566 by Ben Gamari at 2019-11-24T14:33:54-05:00 configure: Fix HAVE_C11_ATOMICS macro Previously we were using AC_DEFINE instead of AC_DEFINE_UNQUOTED, resulted in the variable not being interpolated. Fixes #17505. - - - - - 8b8dc366 by Krzysztof Gogolewski at 2019-11-25T14:37:38+01:00 Remove prefix arrow support for GADTs (#17211) This reverts the change in #9096. The specialcasing done for prefix (->) is brittle and does not support VTA, type families, type synonyms etc. - - - - - 5a08f7d4 by Sebastian Graf at 2019-11-27T00:14:59-05:00 Make warnings for TH splices opt-in In #17270 we have the pattern-match checker emit incorrect warnings. The reason for that behavior is ultimately an inconsistency in whether we treat TH splices as written by the user (`FromSource :: Origin`) or as generated code (`Generated`). This was first reported in #14838. The current solution is to TH splices as `Generated` by default and only treat them as `FromSource` when the user requests so (-fenable-th-splice-warnings). There are multiple reasons for opt-in rather than opt-out: * It's not clear that the user that compiles a splice is the author of the code that produces the warning. Think of the situation where she just splices in code from a third-party library that produces incomplete pattern matches. In this scenario, the user isn't even able to fix that warning. * Gathering information for producing the warnings (pattern-match check warnings in particular) is costly. There's no point in doing so if the user is not interested in those warnings. Fixes #17270, but not #14838, because the proper solution needs a GHC proposal extending the TH AST syntax. - - - - - 8168b42a by Vladislav Zavialov at 2019-11-27T11:32:18+03:00 Whitespace-sensitive bang patterns (#1087, #17162) This patch implements a part of GHC Proposal #229 that covers five operators: * the bang operator (!) * the tilde operator (~) * the at operator (@) * the dollar operator ($) * the double dollar operator ($$) Based on surrounding whitespace, these operators are disambiguated into bang patterns, lazy patterns, strictness annotations, type applications, splices, and typed splices. This patch doesn't cover the (-) operator or the -Woperator-whitespace warning, which are left as future work. - - - - - 9e5477c4 by Ryan Scott at 2019-11-27T20:01:50-05:00 Fix @since annotations for isResourceVanishedError and friends (#17488) - - - - - e122ba33 by Sergei Trofimovich at 2019-11-27T20:02:29-05:00 .gitmodules: tweak 'exception' URL to avoid redirection warnings Avoid initial close warning of form: ``` Cloning into 'exceptions'... warning: redirecting to https://gitlab.haskell.org/ghc/packages/exceptions.git/ ``` Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f84b52a by Philipp Krüger at 2019-11-28T02:54:05-05:00 Reduce boolean blindness in OccInfo(OneOcc) #17482 * Transformed the type aliases `InterestingCxt`, `InsideLam` and `OneBranch` into data types. * Added Semigroup and Monoid instances for use in orOccInfo in OccurAnal.hs * Simplified some usage sites by using pattern matching instead of boolean algebra. Metric Increase: T12150 This increase was on a Mac-build of exactly 1%. This commit does *not* re-intruduce the asymptotic memory usage described in T12150. - - - - - 3748ba3a by Brian Wignall at 2019-11-28T02:54:52-05:00 Fix typos, using Wikipedia list of common typos - - - - - 6c59cc71 by Stefan Schulze Frielinghaus at 2019-11-28T02:55:33-05:00 Fix endian handling of LLVM backend Get rid of CPP macro WORDS_BIGENDIAN which is not defined anymore, and replace it by DynFlag. This fixes partially #17337. - - - - - 6985e0fc by Vladislav Zavialov at 2019-11-28T15:47:53+03:00 Factor out HsSCC/HsCoreAnn/HsTickPragma into HsPragE This is a refactoring with no user-visible changes (except for GHC API users). Consider the HsExpr constructors that correspond to user-written pragmas: HsSCC representing {-# SCC ... #-} HsCoreAnn representing {-# CORE ... #-} HsTickPragma representing {-# GENERATED ... #-} We can factor them out into a separate datatype, HsPragE. It makes the code a bit tidier, especially in the parser. Before this patch: hpc_annot :: { Located ( (([AddAnn],SourceText),(StringLiteral,(Int,Int),(Int,Int))), ((SourceText,SourceText),(SourceText,SourceText)) ) } After this patch: prag_hpc :: { Located ([AddAnn], HsPragE GhcPs) } - - - - - 7f695a20 by Ömer Sinan Ağacan at 2019-11-29T08:25:28-05:00 Pass ModDetails with (partial) ModIface in HscStatus (Partial) ModIface and ModDetails are generated at the same time, but they're passed differently: ModIface is passed in HscStatus consturctors while ModDetails is returned in a tuple. This refactors ModDetails passing so that it's passed around with ModIface in HscStatus constructors. This makes the code more consistent and hopefully easier to understand: ModIface and ModDetails are really very closely related. It makes sense to treat them the same way. - - - - - e921c90f by Ömer Sinan Ağacan at 2019-11-29T08:26:07-05:00 Improve few Foreign.Marshal.Utils docs In copyBytes and moveBytes mention which argument is source and which is destination. Also fixes some of the crazy indentation in the module and cleans trailing whitespace. - - - - - 316f2431 by Sebastian Graf at 2019-11-30T02:57:58-05:00 Hadrian docs: Rename the second "validate" entry to "slow-validate" [ci skip] That would be in line with the implementation. - - - - - 5aba5d32 by Vladislav Zavialov at 2019-11-30T02:58:34-05:00 Remove HasSrcSpan (#17494) Metric Decrease: haddock.compiler - - - - - d1de5c22 by Sylvain Henry at 2019-11-30T02:59:13-05:00 Use Hadrian by default in validate script (#17527) - - - - - 3a96a0b6 by Sebastian Graf at 2019-11-30T02:59:55-05:00 Simpler Semigroup instance for InsideLam and InterestingCtxt This mirrors the definition of `(&&)` and `(||)` now, relieving the Simplifier of a marginal amount of pressure. - - - - - f8cfe81a by Roland Senn at 2019-11-30T20:33:49+01:00 Improve tests for #17171 While backporting MR !1806 to 8.8.2 (!1885) I learnt the following: * Tests with `expect_fail` do not compare `*.stderr` output files. So a test using `expect_fail` will not detect future regressions on the `stderr` output. * To compare the `*.stderr` output files, I have to use the `exit_code(n)` function. * When a release is made, tests with `makefile_test` are converted to use `run_command`. * For the test `T17171a` the return code is `1` when running `makefile_test`, however it's `2` when running `run_command`. Therefore I decided: * To improve my tests for #17171 * To change test T17171a from `expect_fail` to `exit_code(2)` * To change both tests from `makefile_test` to `run_command` - - - - - 2b113fc9 by Vladislav Zavialov at 2019-12-01T08:17:05-05:00 Update DisambECP-related comments - - - - - beed7c3e by Ben Gamari at 2019-12-02T03:41:37-05:00 testsuite: Fix location of typing_stubs module This should fix the build on Debian 8. - - - - - 53251413 by Ben Gamari at 2019-12-02T03:42:14-05:00 testsuite: Don't override LD_LIBRARY_PATH, only prepend NixOS development environments often require that LD_LIBRARY_PATH be set in order to find system libraries. T1407 was overriding LD_LIBRARY_PATH, dropping these directories. Now it merely prepends, its directory. - - - - - 65400314 by Krzysztof Gogolewski at 2019-12-02T03:42:57-05:00 Convert warnings into assertions Since the invariants always hold in the testsuite, we can convert them to asserts. - - - - - 18baed64 by Alan Zimmerman at 2019-12-02T03:43:37-05:00 API Annotations: Unicode '->' on HsForallTy The code fragment type family Proxy2' ∷ ∀ k → k → Type where Proxy2' = Proxy' Generates AnnRarrow instead of AnnRarrowU for the first →. Fixes #17519 - - - - - 717f3236 by Brian Wignall at 2019-12-02T03:44:16-05:00 Fix more typos - - - - - bde48f8e by Ben Gamari at 2019-12-02T11:55:34-05:00 More Haddock syntax in GHC.Hs.Utils As suggested by RyanGlScott in !2163. - - - - - 038bedbc by Ben Gamari at 2019-12-02T11:56:18-05:00 Simplify: Fix pretty-printing of strictness A colleague recently hit the panic in Simplify.addEvals and I noticed that the message is quite unreadable due to incorrect pretty-printing. Fix this. - - - - - c500f652 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix changelog linting logic - - - - - 8ead967d by Ben Gamari at 2019-12-02T11:56:54-05:00 win32-init: Drop workaround for #17480 The `process` changes have now been merged into `hsc2hs`. (cherry picked from commit fa029f53132ad59f847ed012d3b835452cf16615) - - - - - d402209a by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Disable Sphinx build on Debian 8 The docutils version available appears to be too old to support the `table` directive's `:widths:` options. (cherry picked from commit 75764487a96a7a026948b5af5022781872d12baa) - - - - - f1f68824 by Ben Gamari at 2019-12-02T11:56:54-05:00 base: Fix <unistd.h> #include Previously we were including <sys/unistd.h> which is available on glibc but not musl. (cherry picked from commit e44b695ca7cb5f3f99eecfba05c9672c6a22205e) - - - - - 37eb94b3 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Bump Docker images Installs pxz on Centos7 (cherry picked from commit 86960e691f7a600be247c32a7cf795bf9abf7cc4) - - - - - aec98a79 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: pxz is unavailable on CentOS 7 Fall back to xz - - - - - 6708b8e5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Set LANG on CentOS 7 It otherwise seems to default to ascii - - - - - 470ef0e7 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Consolidate release build configuration - - - - - 38338757 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add Debian 10 builds - - - - - 012f13b5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix Windows bindist collection Apparently variable interpolation in the `artifacts.paths` key of `gitlab-ci.yml` doesn't work on Windows as it does on WIndows. (cherry picked from commit 100cc756faa4468ed6950116bae30609c1c3468b) - - - - - a0f09e23 by Ben Gamari at 2019-12-02T11:56:54-05:00 testsuite: Simplify Python <3.5 fallback for TextIO (cherry picked from commit d092d8598694c23bc07cdcc504dff52fa5f33be1) - - - - - 2b2370ec by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add release-x86_64-linux-deb9 job (cherry picked from commit cbedb3c4a90649f474cb716842ba53afc5a642ca) - - - - - b1c206fd by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Always build source tarball (cherry picked from commit 67b5de88ef923971f1980335137e3c7193213abd) - - - - - 4cbd5b47 by Sergei Trofimovich at 2019-12-02T11:57:33-05:00 configure.ac: make cross-compiler detection stricter Be more precise at detecting cross-compilation case. Before the change configuration $ ./configure --host=x86_64-pc-linux-gnu --target=x86_64-gentoo-linux-musl was not considered a cross-target. Even though libcs are different (`glibc` vs. `musl`). Without this patch build fails as: ``` "inplace/bin/ghc-cabal" check libraries/integer-gmp "inplace/bin/ghc-cabal" configure libraries/integer-gmp dist-install \ --with-ghc="/home/slyfox/dev/git/ghc/inplace/bin/ghc-stage1" \ --with-ghc-pkg="/home/slyfox/dev/git/ghc/inplace/bin/ghc-pkg" \ --disable-library-for-ghci --enable-library-vanilla --enable-library-for-ghci \ --enable-library-profiling --enable-shared --with-hscolour="/usr/bin/HsColour" \ --configure-option=CFLAGS="-Wall \ -Werror=unused-but-set-variable -Wno-error=inline \ -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp" \ --configure-option=LDFLAGS=" " --configure-option=CPPFLAGS=" \ " --gcc-options="-Wall -Werror=unused-but-set-variable -Wno-error=inline -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp \ " --with-gcc="x86_64-gentoo-linux-musl-gcc" --with-ld="x86_64-gentoo-linux-musl-ld.gold" --with-ar="x86_64-gentoo-linux-musl-ar" \ --with-alex="/usr/bin/alex" --with-happy="/usr/bin/happy" Configuring integer-gmp-1.0.2.0... configure: WARNING: unrecognized options: --with-compiler checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking target system type... x86_64-pc-linux-gnu checking for gcc... /usr/lib/ccache/bin/x86_64-gentoo-linux-musl-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... configure: error: in `/home/slyfox/dev/git/ghc/libraries/integer-gmp/dist-install/build': configure: error: cannot run C compiled programs. If you meant to cross compile, use `--host'. See `config.log' for more details make[1]: *** [libraries/integer-gmp/ghc.mk:5: libraries/integer-gmp/dist-install/package-data.mk] Error 1 make: *** [Makefile:126: all] Error 2 ``` Note: here `ghc-stage1` is assumed to target `musl` target but is passed `glibc` toolchain. It happens because initial ./configure phase did not detect host/target as different. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f7cb423 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Add `timesInt2#` primop - - - - - fbbe18a2 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Use the new timesInt2# primop in integer-gmp (#9431) - - - - - 5a4b8d0c by Athas at 2019-12-03T00:00:09-05:00 Document RTS behaviour upon encountering '--'. - - - - - 705a16df by Ben Gamari at 2019-12-03T07:11:33-05:00 Make BCO# lifted In #17424 Simon PJ noted that there is a potentially unsafe occurrence of unsafeCoerce#, coercing from an unlifted to lifted type. However, nowhere in the compiler do we assume that a BCO# is not a thunk. Moreover, in the case of a CAF the result returned by `createBCO` *will* be a thunk (as noted in [Updatable CAF BCOs]). Consequently it seems better to rather make BCO# a lifted type and rename it to BCO. - - - - - 35afe4f3 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Use Int# primops in `Bits Int{8,16,32,64}` instances - - - - - 7a51b587 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Add constant folding rule (#16402) narrowN (x .&. m) m .&. (2^N-1) = 2^N-1 ==> narrowN x e.g. narrow16 (x .&. 0x12FFFF) ==> narrow16 x - - - - - 10caee7f by Ben Gamari at 2019-12-03T21:04:50-05:00 users-guide: Add 8.12.1 release notes - - - - - 25019d18 by Ben Gamari at 2019-12-03T21:04:50-05:00 Drop Uniquable constraint for AnnTarget This relied on deriveUnique, which was far too subtle to be safely applied. Thankfully the instance doesn't appear to be used so let's just drop it. - - - - - 78b67ad0 by Ben Gamari at 2019-12-03T21:04:50-05:00 Simplify uniqAway This does two things: * Eliminate all uses of Unique.deriveUnique, which was quite easy to mis-use and extremely subtle. * Rename the previous "derived unique" notion to "local unique". This is possible because the only places where `uniqAway` can be safely used are those where local uniqueness (with respect to some InScopeSet) is sufficient. * Rework the implementation of VarEnv.uniqAway, as discussed in #17462. This should make the operation significantly more efficient than its previous iterative implementation.. Metric Decrease: T9872c T12227 T9233 T14683 T5030 T12545 hie002 Metric Increase: T9961 - - - - - f03a41d4 by Ben Gamari at 2019-12-03T21:05:27-05:00 Elf: Fix link info note generation Previously we would use the `.int` assembler directive to generate 32-bit words in the note section. However, `.int` is note guaranteed to produce 4-bytes; in fact, on some platforms (e.g. AArch64) it produces 8-bytes. Use the `.4bytes` directive to avoid this. Moreover, we used the `.align` directive, which is quite platform dependent. On AArch64 it appears to not even be idempotent (despite what the documentation claims). `.balign` is consequentially preferred as it offers consistent behavior across platforms. - - - - - 84585e5e by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Meaning-preserving SCC annotations (#15730) This patch implements GHC Proposal #176: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0176-scc-parsing.rst Before the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = 1.0 After the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = parse error - - - - - e49e5470 by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Improve error messages for SCC pragmas - - - - - a2b535d9 by Ben Gamari at 2019-12-05T16:07:45-05:00 users guide: Try to silence underfull \hbox warnings We use two tricks, as suggested here [1]: * Use microtype to try to reduce the incidence of underfull boxes * Bump up \hbadness to eliminate the warnings - - - - - 4e47217f by Bodigrim at 2019-12-05T16:07:47-05:00 Make sameNat and sameSymbol proxy-polymorphic - - - - - 8324f0b7 by Bodigrim at 2019-12-05T16:07:47-05:00 Test proxy-polymorphic sameNat and sameSymbol - - - - - 69001f54 by Ben Gamari at 2019-12-05T16:07:48-05:00 nonmoving: Clear segment bitmaps during sweep Previously we would clear the bitmaps of segments which we are going to sweep during the preparatory pause. However, this is unnecessary: the existence of the mark epoch ensures that the sweep will correctly identify non-reachable objects, even if we do not clear the bitmap. We now defer clearing the bitmap to sweep, which happens concurrently with mutation. - - - - - 58a9c429 by Ben Gamari at 2019-12-05T16:07:48-05:00 testsuite: Disable divByZero on non-NCG targets The LLVM backend does not guarantee any particular semantics for division by zero, making this test unreliable across platforms. - - - - - 8280bd8a by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Factor out terminal coloring - - - - - 92a52aaa by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Make performance metric summary more readable Along with some refactoring. - - - - - c4ca29c7 by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Use colors more consistently - - - - - 3354c68e by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Pretty-printing of the * kind Before this patch, GHC always printed the * kind unparenthesized. This led to two issues: 1. Sometimes GHC printed invalid or incorrect code. For example, GHC would print: type F @* x = x when it meant to print: type F @(*) x = x In the former case, instead of a kind application we were getting a type operator (@*). 2. Sometimes GHC printed kinds that were correct but hard to read. Should Either * Int be read as Either (*) Int or as (*) Either Int ? This depends on whether -XStarIsType is enabled, but it would be easier if we didn't have to check for the flag when reading the code. We can solve both problems by assigning (*) a different precedence. Note that Haskell98 kinds are not affected: ((* -> *) -> *) -> * does NOT become (((*) -> (*)) -> (*)) -> (*) The parentheses are added when (*) is used in a function argument position: F * * * becomes F (*) (*) (*) F A * B becomes F A (*) B Proxy * becomes Proxy (*) a * -> * becomes a (*) -> * - - - - - 70dd0e4b by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Parenthesize the * kind in TH.Ppr - - - - - a7a4efbf by Ben Gamari at 2019-12-05T16:07:49-05:00 rts/NonMovingSweep: Fix locking of new mutable list allocation Previously we used allocBlockOnNode_sync in nonmovingSweepMutLists despite the fact that we aren't in the GC and therefore the allocation spinlock isn't in use. This meant that sweep would end up spinning until the next minor GC, when the SM lock was moved away from the SM_MUTEX to the spinlock. This isn't a correctness issue but it sure isn't good for performance. Found thanks for Ward. Fixes #17539. - - - - - f171b358 by Matthias Braun at 2019-12-05T16:07:51-05:00 Fix typo in documentation of Base.hs. - - - - - 9897e8c8 by Gabor Greif at 2019-12-06T21:20:38-05:00 Implement pointer tagging for big families (#14373) Formerly we punted on these and evaluated constructors always got a tag of 1. We now cascade switches because we have to check the tag first and when it is MAX_PTR_TAG then get the precise tag from the info table and switch on that. The only technically tricky part is that the default case needs (logical) duplication. To do this we emit an extra label for it and branch to that from the second switch. This avoids duplicated codegen. Here's a simple example of the new code gen: data D = D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 On a 64-bit system previously all constructors would be tagged 1. With the new code gen D7 and D8 are tagged 7: [Lib.D7_con_entry() { ... {offset c1eu: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] [Lib.D8_con_entry() { ... {offset c1ez: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] When switching we now look at the info table only when the tag is 7. For example, if we derive Enum for the type above, the Cmm looks like this: c2Le: _s2Js::P64 = R1; _c2Lq::P64 = _s2Js::P64 & 7; switch [1 .. 7] _c2Lq::P64 { case 1 : goto c2Lk; case 2 : goto c2Ll; case 3 : goto c2Lm; case 4 : goto c2Ln; case 5 : goto c2Lo; case 6 : goto c2Lp; case 7 : goto c2Lj; } // Read info table for tag c2Lj: _c2Lv::I64 = %MO_UU_Conv_W32_W64(I32[I64[_s2Js::P64 & (-8)] - 4]); if (_c2Lv::I64 != 6) goto c2Lu; else goto c2Lt; Generated Cmm sizes do not change too much, but binaries are very slightly larger, due to the fact that the new instructions are longer in encoded form. E.g. previously entry code for D8 above would be 00000000000001c0 <Lib_D8_con_info>: 1c0: 48 ff c3 inc %rbx 1c3: ff 65 00 jmpq *0x0(%rbp) With this patch 00000000000001d0 <Lib_D8_con_info>: 1d0: 48 83 c3 07 add $0x7,%rbx 1d4: ff 65 00 jmpq *0x0(%rbp) This is one byte longer. Secondly, reading info table directly and then switching is shorter _c1co: movq -1(%rbx),%rax movl -4(%rax),%eax // Switch on info table tag jmp *_n1d5(,%rax,8) than doing the same switch, and then for the tag 7 doing another switch: // When tag is 7 _c1ct: andq $-8,%rbx movq (%rbx),%rax movl -4(%rax),%eax // Switch on info table tag ... Some changes of binary sizes in actual programs: - In NoFib the worst case is 0.1% increase in benchmark "parser" (see NoFib results below). All programs get slightly larger. - Stage 2 compiler size does not change. - In "containers" (the library) size of all object files increases 0.0005%. Size of the test program "bitqueue-properties" increases 0.03%. nofib benchmarks kindly provided by Ömer (@osa1): NoFib Results ============= -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.0% 0.0% -0.0% -0.0% -0.0% CSD +0.0% 0.0% 0.0% +0.0% +0.0% FS +0.0% 0.0% 0.0% +0.0% 0.0% S +0.0% 0.0% -0.0% 0.0% 0.0% VS +0.0% 0.0% -0.0% +0.0% +0.0% VSD +0.0% 0.0% -0.0% +0.0% -0.0% VSM +0.0% 0.0% 0.0% 0.0% 0.0% anna +0.0% 0.0% +0.1% -0.9% -0.0% ansi +0.0% 0.0% -0.0% +0.0% +0.0% atom +0.0% 0.0% 0.0% 0.0% 0.0% awards +0.0% 0.0% -0.0% +0.0% 0.0% banner +0.0% 0.0% -0.0% +0.0% 0.0% bernouilli +0.0% 0.0% +0.0% +0.0% +0.0% binary-trees +0.0% 0.0% -0.0% -0.0% -0.0% boyer +0.0% 0.0% +0.0% 0.0% -0.0% boyer2 +0.0% 0.0% +0.0% 0.0% -0.0% bspt +0.0% 0.0% +0.0% +0.0% 0.0% cacheprof +0.0% 0.0% +0.1% -0.8% 0.0% calendar +0.0% 0.0% -0.0% +0.0% -0.0% cichelli +0.0% 0.0% +0.0% 0.0% 0.0% circsim +0.0% 0.0% -0.0% -0.1% -0.0% clausify +0.0% 0.0% +0.0% +0.0% 0.0% comp_lab_zift +0.0% 0.0% +0.0% 0.0% -0.0% compress +0.0% 0.0% +0.0% +0.0% 0.0% compress2 +0.0% 0.0% 0.0% 0.0% 0.0% constraints +0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 +0.0% 0.0% +0.0% 0.0% 0.0% cryptarithm2 +0.0% 0.0% +0.0% -0.0% 0.0% cse +0.0% 0.0% +0.0% +0.0% 0.0% digits-of-e1 +0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 +0.0% 0.0% +0.0% -0.0% -0.0% dom-lt +0.0% 0.0% +0.0% +0.0% 0.0% eliza +0.0% 0.0% -0.0% +0.0% 0.0% event +0.0% 0.0% -0.0% -0.0% -0.0% exact-reals +0.0% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.0% 0.0% -0.0% -0.0% -0.0% expert +0.0% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.0% 0.0% +0.0% 0.0% 0.0% fasta +0.0% 0.0% -0.0% -0.0% -0.0% fem +0.0% 0.0% +0.0% +0.0% +0.0% fft +0.0% 0.0% +0.0% -0.0% -0.0% fft2 +0.0% 0.0% +0.0% +0.0% +0.0% fibheaps +0.0% 0.0% +0.0% +0.0% 0.0% fish +0.0% 0.0% +0.0% +0.0% 0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.0% 0.0% +0.0% -0.0% +0.0% gamteb +0.0% 0.0% +0.0% -0.0% -0.0% gcd +0.0% 0.0% +0.0% +0.0% 0.0% gen_regexps +0.0% 0.0% +0.0% -0.0% -0.0% genfft +0.0% 0.0% -0.0% -0.0% -0.0% gg +0.0% 0.0% 0.0% -0.0% 0.0% grep +0.0% 0.0% +0.0% +0.0% +0.0% hidden +0.0% 0.0% +0.0% -0.0% -0.0% hpg +0.0% 0.0% +0.0% -0.1% -0.0% ida +0.0% 0.0% +0.0% -0.0% -0.0% infer +0.0% 0.0% -0.0% -0.0% -0.0% integer +0.0% 0.0% -0.0% -0.0% -0.0% integrate +0.0% 0.0% 0.0% +0.0% 0.0% k-nucleotide +0.0% 0.0% -0.0% -0.0% -0.0% kahan +0.0% 0.0% -0.0% -0.0% -0.0% knights +0.0% 0.0% +0.0% -0.0% -0.0% lambda +0.0% 0.0% +1.2% -6.1% -0.0% last-piece +0.0% 0.0% +0.0% -0.0% -0.0% lcss +0.0% 0.0% +0.0% -0.0% -0.0% life +0.0% 0.0% +0.0% -0.0% -0.0% lift +0.0% 0.0% +0.0% +0.0% 0.0% linear +0.0% 0.0% +0.0% +0.0% +0.0% listcompr +0.0% 0.0% -0.0% -0.0% -0.0% listcopy +0.0% 0.0% -0.0% -0.0% -0.0% maillist +0.0% 0.0% +0.0% -0.0% -0.0% mandel +0.0% 0.0% +0.0% +0.0% +0.0% mandel2 +0.0% 0.0% +0.0% +0.0% -0.0% mate +0.0% 0.0% +0.0% +0.0% +0.0% minimax +0.0% 0.0% -0.0% +0.0% -0.0% mkhprog +0.0% 0.0% +0.0% +0.0% +0.0% multiplier +0.0% 0.0% 0.0% +0.0% -0.0% n-body +0.0% 0.0% +0.0% -0.0% -0.0% nucleic2 +0.0% 0.0% +0.0% +0.0% -0.0% para +0.0% 0.0% +0.0% +0.0% +0.0% paraffins +0.0% 0.0% +0.0% +0.0% +0.0% parser +0.1% 0.0% +0.4% -1.7% -0.0% parstof +0.0% 0.0% -0.0% -0.0% -0.0% pic +0.0% 0.0% +0.0% 0.0% -0.0% pidigits +0.0% 0.0% -0.0% -0.0% -0.0% power +0.0% 0.0% +0.0% -0.0% -0.0% pretty +0.0% 0.0% +0.0% +0.0% +0.0% primes +0.0% 0.0% +0.0% 0.0% 0.0% primetest +0.0% 0.0% +0.0% +0.0% +0.0% prolog +0.0% 0.0% +0.0% +0.0% +0.0% puzzle +0.0% 0.0% +0.0% +0.0% +0.0% queens +0.0% 0.0% 0.0% +0.0% +0.0% reptile +0.0% 0.0% +0.0% +0.0% 0.0% reverse-complem +0.0% 0.0% -0.0% -0.0% -0.0% rewrite +0.0% 0.0% +0.0% 0.0% -0.0% rfib +0.0% 0.0% +0.0% +0.0% +0.0% rsa +0.0% 0.0% +0.0% +0.0% +0.0% scc +0.0% 0.0% +0.0% +0.0% +0.0% sched +0.0% 0.0% +0.0% +0.0% +0.0% scs +0.0% 0.0% +0.0% +0.0% 0.0% simple +0.0% 0.0% +0.0% +0.0% +0.0% solid +0.0% 0.0% +0.0% +0.0% 0.0% sorting +0.0% 0.0% +0.0% -0.0% 0.0% spectral-norm +0.0% 0.0% -0.0% -0.0% -0.0% sphere +0.0% 0.0% +0.0% -1.0% 0.0% symalg +0.0% 0.0% +0.0% +0.0% +0.0% tak +0.0% 0.0% +0.0% +0.0% +0.0% transform +0.0% 0.0% +0.4% -1.3% +0.0% treejoin +0.0% 0.0% +0.0% -0.0% 0.0% typecheck +0.0% 0.0% -0.0% +0.0% 0.0% veritas +0.0% 0.0% +0.0% -0.1% +0.0% wang +0.0% 0.0% +0.0% +0.0% +0.0% wave4main +0.0% 0.0% +0.0% 0.0% -0.0% wheel-sieve1 +0.0% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.0% 0.0% +0.0% +0.0% 0.0% x2n1 +0.0% 0.0% +0.0% +0.0% 0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -6.1% -0.0% Max +0.1% 0.0% +1.2% +0.0% +0.0% Geometric Mean +0.0% -0.0% +0.0% -0.1% -0.0% NoFib GC Results ================ -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim +0.0% 0.0% -0.0% -0.0% -0.0% constraints +0.0% 0.0% -0.0% 0.0% -0.0% fibheaps +0.0% 0.0% 0.0% -0.0% -0.0% fulsom +0.0% 0.0% 0.0% -0.6% -0.0% gc_bench +0.0% 0.0% 0.0% 0.0% -0.0% hash +0.0% 0.0% -0.0% -0.0% -0.0% lcss +0.0% 0.0% 0.0% -0.0% 0.0% mutstore1 +0.0% 0.0% 0.0% -0.0% -0.0% mutstore2 +0.0% 0.0% +0.0% -0.0% -0.0% power +0.0% 0.0% -0.0% 0.0% -0.0% spellcheck +0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.6% -0.0% Max +0.0% 0.0% +0.0% 0.0% 0.0% Geometric Mean +0.0% +0.0% +0.0% -0.1% +0.0% Fixes #14373 These performance regressions appear to be a fluke in CI. See the discussion in !1742 for details. Metric Increase: T6048 T12234 T12425 Naperian T12150 T5837 T13035 - - - - - ee07421f by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Work in progress on coercionLKind, coercionRKind This is a preliminary patch for #17515 - - - - - 0a4ca9eb by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Split up coercionKind This patch implements the idea in #17515, splitting `coercionKind` into: * `coercion{Left,Right}Kind`, which computes the left/right side of the pair * `coercionKind`, which computes the pair of coercible types This is reduces allocation since we frequently only need only one side of the pair. Specifically, we see the following improvements on x86-64 Debian 9: | test | new | old | relative chg. | | :------- | ---------: | ------------: | ------------: | | T5030 | 695537752 | 747641152.0 | -6.97% | | T5321Fun | 449315744 | 474009040.0 | -5.21% | | T9872a | 2611071400 | 2645040952.0 | -1.28% | | T9872c | 2957097904 | 2994260264.0 | -1.24% | | T12227 | 773435072 | 812367768.0 | -4.79% | | T12545 | 3142687224 | 3215714752.0 | -2.27% | | T14683 | 9392407664 | 9824775000.0 | -4.40% | Metric Decrease: T12545 T9872a T14683 T5030 T12227 T9872c T5321Fun T9872b - - - - - d46a72e1 by Gabor Greif at 2019-12-09T12:05:15-05:00 Fix comment typos The below is only necessary to fix the CI perf fluke that happened in 9897e8c8ef0b19a9571ef97a1d9bb050c1ee9121: ------------------------- Metric Decrease: T5837 T6048 T9020 T12425 T12234 T13035 T12150 Naperian ------------------------- - - - - - e3bba7e4 by Micha Wiedenmann at 2019-12-10T19:52:44-05:00 users guide: Motivation of DefaultSignatures - - - - - 843ceb38 by Ben Gamari at 2019-12-10T19:53:54-05:00 rts: Add a long form flag to enable the non-moving GC The old flag, `-xn`, was quite cryptic. Here we add `--nonmoving-gc` in addition. - - - - - 921d3238 by Ryan Scott at 2019-12-10T19:54:34-05:00 Ignore unary constraint tuples during typechecking (#17511) We deliberately avoid defining a magical `Unit%` class, for reasons that I have expounded upon in the newly added `Note [Ignore unary constraint tuples]` in `TcHsType`. However, a sneaky user could try to insert `Unit%` into their program by way of Template Haskell, leading to the interface-file error observed in #17511. To avoid this, any time we encounter a unary constraint tuple during typechecking, we drop the surrounding constraint tuple application. This is safe to do since `Unit% a` and `a` would be semantically equivalent (unlike other forms of unary tuples). Fixes #17511. - - - - - 436ec9f3 by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 2f6b434f by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 7a5a6e07 by Ben Gamari at 2019-12-10T19:56:25-05:00 base: Fix incorrect @since in GHC.Natural Fixes #17547. - - - - - 2bbfaf8a by Ben Gamari at 2019-12-10T19:57:01-05:00 hadrian: AArch64 supports the GHCi interpreter and SMP I'm not sure how this was omitted from the list of supported architectures. - - - - - 8f1ceb67 by John Ericson at 2019-12-10T19:57:39-05:00 Move Int# section of primops.txt.pp This matches the organization of the fixed-sized ones, and keeps each Int* next to its corresponding Word*. - - - - - 7a823b0f by John Ericson at 2019-12-10T19:57:39-05:00 Move Int64# and Word64# sections of primops.txt.pp This way it is next to the other fixed-sized ones. - - - - - 8dd9929a by Ben Gamari at 2019-12-10T19:58:19-05:00 testsuite: Add (broken) test for #17510 - - - - - 6e47a76a by Ben Gamari at 2019-12-10T19:58:59-05:00 Re-layout validate script This script was previously a whitespace nightmare. - - - - - f80c4a66 by Crazycolorz5 at 2019-12-11T14:12:17-05:00 rts: Specialize hashing at call site rather than in struct. Separate word and string hash tables on the type level, and do not store the hashing function. Thus when a different hash function is desire it is provided upon accessing the table. This is worst case the same as before the change, and in the majority of cases is better. Also mark the functions for aggressive inlining to improve performance. {F1686506} Reviewers: bgamari, erikd, simonmar Subscribers: rwbarton, thomie, carter GHC Trac Issues: #13165 Differential Revision: https://phabricator.haskell.org/D4889 - - - - - 2d1b9619 by Richard Eisenberg at 2019-12-11T14:12:55-05:00 Warn on inferred polymorphic recursion Silly users sometimes try to use visible dependent quantification and polymorphic recursion without a CUSK or SAK. This causes unexpected errors. So we now adjust expectations with a bit of helpful messaging. Closes #17541 and closes #17131. test cases: dependent/should_fail/T{17541{,b},17131} - - - - - 4dde485e by Oleg Grenrus at 2019-12-12T02:24:46-05:00 Add --show-unit-ids flag to ghc-pkg I only added it into --simple-output and ghc-pkg check output; there are probably other places where it can be adopted. - - - - - e6e1ec08 by Ben Gamari at 2019-12-12T02:25:33-05:00 testsuite: Simplify and clarify performance test baseline search The previous implementation was extremely complicated, seemingly to allow the local and CI namespaces to be searched incrementally. However, it's quite unclear why this is needed and moreover the implementation seems to have had quadratic runtime cost in the search depth(!). - - - - - 29c4609c by Ben Gamari at 2019-12-12T02:26:19-05:00 testsuite: Add test for #17549 - - - - - 9f0ee253 by Ben Gamari at 2019-12-12T02:26:56-05:00 gitlab-ci: Move -dwarf and -debug jobs to full-build stage This sacrifices some precision in favor of improving parallelism. - - - - - 7179b968 by Ben Gamari at 2019-12-12T02:27:34-05:00 Revert "rts: Drop redundant flags for libffi" This seems to have regressed builds using `--with-system-libffi` (#17520). This reverts commit 3ce18700f80a12c48a029b49c6201ad2410071bb. - - - - - cc7d5650 by Oleg Grenrus at 2019-12-16T10:20:56+02:00 Having no shake upper bound is irresposible Given that shake is far from "done" API wise, and is central component to the build system. - - - - - 9431f905 by Oleg Grenrus at 2019-12-16T10:55:50+02:00 Add index-state to hadrian/cabal.project Then one is freer to omit upper bounds, as we won't pick any new entries on Hackage while building hadrian itself. - - - - - 3e17a866 by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Remove dataConSig As suggested in #17291 - - - - - 75355fde by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Use "OrCoVar" functions less As described in #17291, we'd like to separate coercions and expressions in a more robust fashion. This is a small step in this direction. - `mkLocalId` now panicks on a covar. Calls where this was not the case were changed to `mkLocalIdOrCoVar`. - Don't use "OrCoVar" functions in places where we know the type is not a coercion. - - - - - f9686e13 by Richard Eisenberg at 2019-12-16T19:32:21-05:00 Do more validity checks for quantified constraints Close #17583. Test case: typecheck/should_fail/T17563 - - - - - af763765 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Fix Windows artifact collection Variable interpolation in gitlab-ci.yml apparently doesn't work. Sigh. - - - - - e6d4b902 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Debian 10 - - - - - 8ba650e9 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Allow debian 8 build to fail The python release shipped with deb8 (3.3) is too old for our testsuite driver. - - - - - ac25a3f6 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Alpine - - - - - cc628088 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Another approach for xz detection - - - - - 37d788ab by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Re-add release-x86_64-deb9 job Also eliminate some redundancy. - - - - - f8279138 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Drop redundant release-x86_64-linux-deb9 job - - - - - 8148ff06 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark cgrun057 as broken on ARMv7 Due to #17554. It's very surprising that this only occurs on ARMv7 but this is the only place I've seen this failure thusfar. - - - - - 85e5696d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark prog001 as fragile on ARMv7 Due to #17555. - - - - - a5f0aab0 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T10272 as broken on ARMv7 Due to #17556. - - - - - 1e6827c6 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T13825-debugger as broken on ARMv7 Due to #17557. - - - - - 7cef0b7d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T14028 as broken on ARMv7 Due to #17558. - - - - - 6ea4eb4b by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Make ghc_built_by_llvm check more precise Previously it would hackily look at the flavour name to determine whether LLVM was used to build stage2 ghc. However, this didn't work at all with Hadrian and would miss cases like ARM where we use the LLVM backend by default. See #16087 for the motivation for why ghc_built_by_llvm is needed at all. This should catch one of the ARMv7 failures described in #17555. - - - - - c3e82bf7 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T5435_* tests as broken on ARM `T5435_v_asm_a`, `T5435_v_asm_b`, and `T5435_v_gcc` all fail on ARMv7. See #17559. - - - - - eb2aa851 by Ben Gamari at 2019-12-17T07:24:40-05:00 gitlab-ci: Don't allow armv7 jobs to fail - - - - - efc92216 by Ben Gamari at 2019-12-17T07:24:40-05:00 Revert "testsuite: Mark cgrun057 as broken on ARMv7" This reverts commit 6cfc47ec8a478e1751cb3e7338954da1853c3996. - - - - - 1d2bb9eb by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark print002 as fragile on ARM Due to #17557. Also accepting spurious performance change. Metric Decrease: T1969 - - - - - 41f4e4fb by Josh Meredith at 2019-12-17T07:25:17-05:00 Fix ambiguous occurence error when building Hadrian - - - - - 4374983a by Josh Meredith at 2019-12-17T07:25:17-05:00 Rename SphinxMode constructors - - - - - a8f7ecd5 by Josh Meredith at 2019-12-17T07:25:17-05:00 Use *Mode suffix instead of *M - - - - - 58655b9d by Sylvain Henry at 2019-12-18T13:43:37+01:00 Add GHC-API logging hooks * Add 'dumpAction' hook to DynFlags. It allows GHC API users to catch dumped intermediate codes and information. The format of the dump (Core, Stg, raw text, etc.) is now reported allowing easier automatic handling. * Add 'traceAction' hook to DynFlags. Some dumps go through the trace mechanism (for instance unfoldings that have been considered for inlining). This is problematic because: 1) dumps aren't written into files even with -ddump-to-file on 2) dumps are written on stdout even with GHC API 3) in this specific case, dumping depends on unsafe globally stored DynFlags which is bad for GHC API users We introduce 'traceAction' hook which allows GHC API to catch those traces and to avoid using globally stored DynFlags. * Avoid dumping empty logs via dumpAction/traceAction (but still write empty files to keep the existing behavior) - - - - - fad866e0 by Moritz Kiefer at 2019-12-19T11:15:39-05:00 Avoid race condition in hDuplicateTo In our codebase we have some code along the lines of ``` newStdout <- hDuplicate stdout stderr `hDuplicateTo` stdout ``` to avoid stray `putStrLn`s from corrupting a protocol (LSP) that is run over stdout. On CI we have seen a bunch of issues where `dup2` returned `EBUSY` so this fails with `ResourceExhausted` in Haskell. I’ve spent some time looking at the docs for `dup2` and the code in `base` and afaict the following race condition is being triggered here: 1. The user calls `hDuplicateTo stderr stdout`. 2. `hDuplicateTo` calls `hClose_help stdout_`, this closes the file handle for stdout. 3. The file handle for stdout is now free, so another thread allocating a file might get stdout. 4. If `dup2` is called while `stdout` (now pointing to something else) is half-open, it returns EBUSY. I think there might actually be an even worse case where `dup2` is run after FD 1 is fully open again. In that case, you will end up not just redirecting the original stdout to stderr but also the whatever resulted in that file handle being allocated. As far as I can tell, `dup2` takes care of closing the file handle itself so there is no reason to do this in `hDuplicateTo`. So this PR replaces the call to `hClose_help` by the only part of `hClose_help` that we actually care about, namely, `flushWriteBuffer`. I tested this on our codebase fairly extensively and haven’t been able to reproduce the issue with this patch. - - - - - 0c114c65 by Sylvain Henry at 2019-12-19T11:16:17-05:00 Handle large ARR_WORDS in heap census (fix #17572) We can do a heap census with a non-profiling RTS. With a non-profiling RTS we don't zero superfluous bytes of shrunk arrays hence a need to handle the case specifically to avoid a crash. Revert part of a586b33f8e8ad60b5c5ef3501c89e9b71794bbed - - - - - 1a0d1a65 by John Ericson at 2019-12-20T10:50:22-05:00 Deduplicate copied monad failure handler code - - - - - 70e56b27 by Ryan Scott at 2019-12-20T10:50:57-05:00 lookupBindGroupOcc: recommend names in the same namespace (#17593) Previously, `lookupBindGroupOcc`'s error message would recommend all similar names in scope, regardless of whether they were type constructors, data constructors, or functions, leading to the confusion witnessed in #17593. This is easily fixed by only recommending names in the same namespace, using the `nameSpacesRelated` function. Fixes #17593. - - - - - 3c12355e by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN Include header file `ghcautoconf.h` where the CPP macro `WORDS_BIGENDIAN` is defined. This finally fixes #17337 (in conjunction with commit 6c59cc71dc). - - - - - 11f8eef5 by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 fixup! Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN - - - - - 40327b03 by Sylvain Henry at 2019-12-24T01:04:24-05:00 Remove outdated comment - - - - - aeea92ef by Sylvain Henry at 2019-12-25T19:23:54-05:00 Switch to ReadTheDocs theme for the user-guide - - - - - 26493eab by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix copy-paste error in comment - - - - - 776df719 by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix comment about minimal gcc version to be consistent what FP_GCC_VERSION requires - - - - - 3b17114d by Ömer Sinan Ağacan at 2019-12-26T14:09:11-05:00 Minor refactor in ghc.cabal.in: - Remove outdated comments - Move cutils.c from parser to cbits - Remove unused cutils.h - - - - - 334290b6 by Ryan Scott at 2019-12-26T14:09:48-05:00 Replace panic/notHandled with noExtCon in DsMeta There are many spots in `DsMeta` where `panic` or `notHandled` is used after pattern-matching on a TTG extension constructor. This is overkill, however, as using `noExtCon` would work just as well. This patch switches out these panics for `noExtCon`. - - - - - 68252aa3 by Ben Gamari at 2019-12-27T15:11:38-05:00 testsuite: Skip T17499 when built against integer-simple Since it routinely times out in CI. - - - - - 0c51aeeb by Gabor Greif at 2019-12-27T15:12:17-05:00 suppress popup dialog about missing Xcode at configure tested with `bash` and `zsh`. - - - - - 8d76bcc2 by Gabor Greif at 2019-12-27T15:12:17-05:00 while at it rename XCode to the official Xcode - - - - - 47a68205 by Ben Gamari at 2019-12-27T15:12:55-05:00 testsuite: Mark cgrun057 as fragile on ARM As reported in #17554. Only marking on ARM for now although there is evidence to suggest that the issue may occur on other platforms as well. - - - - - d03dec8f by Gabor Greif at 2019-12-27T15:13:32-05:00 use shell variable CcLlvmBackend for test Previously we used `AC_DEFINE`d variable `CC_LLVM_BACKEND` which has an empty shell expansion. - - - - - 2528e684 by Ben Gamari at 2019-12-30T06:51:32-05:00 driver: Include debug level in the recompilation check hash Fixes #17586. - - - - - f14bb50b by Ben Gamari at 2019-12-30T06:52:09-05:00 rts: Ensure that nonmoving gc isn't used with profiling - - - - - b426de37 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Ensure that entry labels don't have predecessors The LLVM IR forbids the entry label of a procedure from having any predecessors. In the case of a simple looping function the LLVM code generator broke this invariant, as noted in #17589. Fix this by moving the function prologue to its own basic block, as suggested by @kavon in #11649. Fixes #11649 and #17589. - - - - - 613f7265 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Drop old fix for #11649 This was a hack which is no longer necessary now since we introduce a dedicated entry block for each procedure. - - - - - fdeffa5e by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Error on invalid --numa flags Previously things like `+RTS --numa-debug` would enable NUMA support, despite being an invalid flag. - - - - - 9ce3ba68 by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Fix --debug-numa mode under Docker As noted in #17606, Docker disallows the get_mempolicy syscall by default. This caused numerous tests to fail under CI in the `debug_numa` way. Avoid this by disabling the NUMA probing logic when --debug-numa is in use, instead setting n_numa_nodes in RtsFlags.c. Fixes #17606. - - - - - 5baa2a43 by Ben Gamari at 2019-12-30T06:54:01-05:00 testsuite: Disable derefnull when built with LLVM LLVM does not guarantee any particular semantics when dereferencing null pointers. Consequently, this test actually passes when built with the LLVM backend. - - - - - bd544d3d by Ben Gamari at 2019-12-30T06:54:38-05:00 hadrian: Track hash of Cabal Setup builder arguments Lest we fail to rebuild when they change. Fixes #17611. - - - - - 6e2c495e by Ben Gamari at 2019-12-30T06:55:19-05:00 TcIface: Fix inverted logic in typechecking of source ticks Previously we would throw away source ticks when the debug level was non-zero. This is precisely the opposite of what was intended. Fixes #17616. Metric Decrease: T13056 T9020 T9961 T12425 - - - - - 7fad387d by Ben Gamari at 2019-12-30T06:55:55-05:00 perf_notes: Add --zero-y argument This makes it easier to see the true magnitude of fluctuations. Also do some house-keeping in the argument parsing department. - - - - - 0d42b287 by Ben Gamari at 2019-12-30T06:55:55-05:00 testsuite: Enlarge acceptance window for T1969 As noted in #17624, it's quite unstable, especially, for some reason, on i386 and armv7 (something about 32-bit platforms perhaps?). Metric Increase: T1969 - - - - - eb608235 by Sylvain Henry at 2019-12-31T14:22:32-05:00 Module hierarchy (#13009): Stg - - - - - d710fd66 by Vladislav Zavialov at 2019-12-31T14:23:10-05:00 Testsuite: update some Haddock tests Fixed tests: * haddockA039: added to all.T * haddockE004: replaced with T17561 (marked as expect_broken) New tests: * haddockA040: deriving clause for a data instance * haddockA041: haddock and CPP #include - - - - - 859ebdd4 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add "-Iw" RTS flag for minimum wait between idle GCs (#11134) - - - - - dd4b6551 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add additional Note explaining the -Iw flag - - - - - c4279ff1 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Fix some sloppy indentation - - - - - b84c09d5 by Ömer Sinan Ağacan at 2019-12-31T23:45:19-05:00 Tweak Cmm dumps to avoid generating sections for empty groups When dumping Cmm groups check if the group is empty, to avoid generating empty sections in dump files like ==================== Output Cmm ==================== [] Also fixes a few bad indentation in the code around changes. - - - - - b2e0323f by Gabor Greif at 2020-01-03T21:22:36-05:00 Simplify mrStr - - - - - 3c9dc06b by Brian Wignall at 2020-01-04T15:55:06-05:00 Fix typos, via a Levenshtein-style corrector - - - - - d561c8f6 by Sylvain Henry at 2020-01-04T15:55:46-05:00 Add Cmm related hooks * stgToCmm hook * cmmToRawCmm hook These hooks are used by Asterius and could be useful to other clients of the GHC API. It increases the Parser dependencies (test CountParserDeps) to 184. It's still less than 200 which was the initial request (cf https://mail.haskell.org/pipermail/ghc-devs/2019-September/018122.html) so I think it's ok to merge this. - - - - - ae6b6276 by Oleg Grenrus at 2020-01-04T15:56:22-05:00 Update to Cabal submodule to v3.2.0.0-alpha3 Metric Increase: haddock.Cabal - - - - - 073f7cfd by Vladislav Zavialov at 2020-01-04T15:56:59-05:00 Add lexerDbg to dump the tokens fed to the parser This a small utility function that comes in handy when debugging the lexer and the parser. - - - - - 558d4d4a by Sylvain Henry at 2020-01-04T15:57:38-05:00 Split integerGmpInternals test in several parts This is to prepare for ghc-bignum which implements some but not all of gmp functions. - - - - - 4056b966 by Ben Gamari at 2020-01-04T15:58:15-05:00 testsuite: Mark cgrun057 as fragile on all platforms I have seen this fail both on x86-64/Debian 9 and armv7/Debian 9 See #17554. - - - - - 5ffea0c6 by Tamar Christina at 2020-01-06T18:38:37-05:00 Fix overflow. - - - - - 99a9f51b by Sylvain Henry at 2020-01-06T18:39:22-05:00 Module hierarchy: Iface (cf #13009) - - - - - 7aa4a061 by Ben Gamari at 2020-01-07T13:11:48-05:00 configure: Only check GCC version if CC is GCC Also refactor FP_GCC_EXTRA_FLAGS in a few ways: * We no longer support compilers which lack support for -fno-builtin and -fwrapv so remove the condition on GccVersion * These flags are only necessary when using the via-C backend so make them conditional on Unregisterised. Fixes #15742. - - - - - 0805ed7e by John Ericson at 2020-01-07T13:12:25-05:00 Use non-empty lists to remove partiality in matching code - - - - - 7844f3a8 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Mark T17073 as broken on Windows Due to #17607. - - - - - acf40cae by Ben Gamari at 2020-01-07T13:13:02-05:00 gitlab-ci: Disallow Windows from failing - - - - - 34bc02c7 by Ben Gamari at 2020-01-07T13:13:02-05:00 configure: Find Python3 for testsuite In addition, we prefer the Mingw64 Python distribution on Windows due to #17483. - - - - - e35fe8d5 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Fix Windows platform test Previously we used platform.system() and while this worked fine (e.g. returned `Windows`, as expected) locally under both msys and MingW64 Python distributions, it inexplicably returned `MINGW64_NT-10.0` under MingW64 Python on CI. It seems os.name is more reliable so we now use that instead.. - - - - - 48ef6217 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Rename push-test-metrics.sh to test-metrics.sh Refactoring to follow. - - - - - 2234fa92 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Pull test metrics before running testsuite Otherwise the testsuite driver may not have an up-to-date baseline. - - - - - 1ca9adbc by Sylvain Henry at 2020-01-07T13:14:18-05:00 Remove `parallel` check from configure.ac `parallel` is no longer a submodule since 3cb063c805ec841ca33b8371ef8aba9329221b6c - - - - - b69a3460 by Ryan Scott at 2020-01-07T13:14:57-05:00 Monomorphize HsModule to GhcPs (#17642) Analyzing the call sites for `HsModule` reveals that it is only ever used with parsed code (i.e., `GhcPs`). This simplifies `HsModule` by concretizing its `pass` parameter to always be `GhcPs`. Fixes #17642. - - - - - d491a679 by Sylvain Henry at 2020-01-08T06:16:31-05:00 Module hierarchy: Renamer (cf #13009) - - - - - d589410f by Ben Gamari at 2020-01-08T06:17:09-05:00 Bump haskeline submodule to 0.8.0.1 (cherry picked from commit feb3b955402d53c3875dd7a9a39f322827e5bd69) - - - - - 923a1272 by Ryan Scott at 2020-01-08T06:17:47-05:00 Print Core type applications with no whitespace after @ (#17643) This brings the pretty-printer for Core in line with how visible type applications are normally printed: namely, with no whitespace after the `@` character (i.e., `f @a` instead of `f @ a`). While I'm in town, I also give the same treatment to type abstractions (i.e., `\(@a)` instead of `\(@ a)`) and coercion applications (i.e., `f @~x` instead of `f @~ x`). Fixes #17643. - - - - - 49f83a0d by Adam Sandberg Eriksson at 2020-01-12T21:28:09-05:00 improve docs for HeaderInfo.getImports [skip ci] - - - - - 9129210f by Matthew Pickering at 2020-01-12T21:28:47-05:00 Overloaded Quotation Brackets (#246) This patch implements overloaded quotation brackets which generalise the desugaring of all quotation forms in terms of a new minimal interface. The main change is that a quotation, for example, [e| 5 |], will now have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass contains a single method for generating new names which is used when desugaring binding structures. The return type of functions from the `Lift` type class, `lift` and `liftTyped` have been restricted to `forall m . Quote m => m Exp` rather than returning a result in a Q monad. More details about the feature can be read in the GHC proposal. https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst - - - - - 350e2b78 by Richard Eisenberg at 2020-01-12T21:29:27-05:00 Don't zap to Any; error instead This changes GHC's treatment of so-called Naughty Quantification Candidates to issue errors, instead of zapping to Any. Close #16775. No new test cases, because existing ones cover this well. - - - - - 0b5ddc7f by Brian Wignall at 2020-01-12T21:30:08-05:00 Fix more typos, via an improved Levenshtein-style corrector - - - - - f732dbec by Ben Gamari at 2020-01-12T21:30:49-05:00 gitlab-ci: Retain bindists used by head.hackage for longer Previously we would keep them for two weeks. However, on the stable branches two weeks can easily elapse with no pushes. - - - - - c8636da5 by Sylvain Henry at 2020-01-12T21:31:30-05:00 Fix LANG=C for readelf invocation in T14999 The test fails when used with LANG=fr_FR.UTF-8 - - - - - 077a88de by Jean-Baptiste Mazon at 2020-01-12T21:32:08-05:00 users-guide/debug-info: typo “behivior” - - - - - 61916c5d by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Add comments about TH levels - - - - - 1fd766ca by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Comments about constraint floating - - - - - de01427e by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Minor refactor around quantified constraints This patch clarifies a dark corner of quantified constraints. * See Note [Yukky eq_sel for a HoleDest] in TcSMonad * Minor refactor, breaking out new function TcInteract.doTopReactEqPred - - - - - 30be3bf1 by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Comments in TcHsType - - - - - c5977d4d by Sebastian Graf at 2020-01-16T05:58:58-05:00 Better documentation for mkEtaWW [skip ci] So that hopefully I understand it faster next time. Also got rid of the confusing `orig_expr`, which makes the call site in `etaExpand` look out of sync with the passed `n` (which is not the original `n`). - - - - - 22c0bdc3 by John Ericson at 2020-01-16T05:59:37-05:00 Handle TagToEnum in the same big case as the other primops Before, it was a panic because it was handled above. But there must have been an error in my reasoning (another caller?) because #17442 reported the panic was hit. But, rather than figuring out what happened, I can just make it impossible by construction. By adding just a bit more bureaucracy in the return types, I can handle TagToEnum in the same case as all the others, so the big case is is now total, and the panic is removed. Fixes #17442 - - - - - ee5d63f4 by John Ericson at 2020-01-16T05:59:37-05:00 Get rid of OpDest `OpDest` was basically a defunctionalization. Just turn the code that cased on it into those functions, and call them directly. - - - - - 1ff55226 by John Ericson at 2020-01-16T06:00:16-05:00 Remove special case case of bool during STG -> C-- Allow removing the no longer needed cgPrimOp, getting rid of a small a small layer violation too. Change which made the special case no longer needed was #6135 / 6579a6c73082387f82b994305011f011d9d8382b, which dates back to 2013, making me feel better. - - - - - f416fe64 by Adam Wespiser at 2020-01-16T06:00:53-05:00 replace dead html link (fixes #17661) - - - - - f6bf2ce8 by Sebastian Graf at 2020-01-16T06:01:32-05:00 Revert "`exprOkForSpeculation` for Note [IO hack in the demand analyser]" This reverts commit ce64b397777408731c6dd3f5c55ea8415f9f565b on the grounds of the regression it would introduce in a couple of packages. Fixes #17653. Also undoes a slight metric increase in #13701 introduced by that commit that we didn't see prior to !1983. Metric Decrease: T13701 - - - - - a71323ff by Ben Gamari at 2020-01-17T08:43:16-05:00 gitlab-ci: Don't FORCE_SYMLINKS on Windows Not all runners have symlink permissions enabled. - - - - - 0499e3bc by Ömer Sinan Ağacan at 2020-01-20T15:31:33-05:00 Fix +RTS -Z flag documentation Stack squeezing is done on context switch, not on GC or stack overflow. Fix the documentation. Fixes #17685 [ci skip] - - - - - a661df91 by Ömer Sinan Ağacan at 2020-01-20T15:32:13-05:00 Document Stg.FVs module Fixes #17662 [ci skip] - - - - - db24e480 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Don't trash STG registers Fixes #13904. - - - - - f3d7fdb3 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix typo in readnone attribute - - - - - 442751c6 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Add lower-expect to the -O0 optimisation set @kavon says that this will improve block layout for stack checks. - - - - - e90ecc93 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix #14251 Fixes the calling convention for functions passing raw SSE-register values by adding padding as needed to get the values in the right registers. This problem cropped up when some args were unused an dropped from the live list. This folds together 2e23e1c7de01c92b038e55ce53d11bf9db993dd4 and 73273be476a8cc6c13368660b042b3b0614fd928 previously from @kavon. Metric Increase: T12707 ManyConstructors - - - - - 66e511a4 by Ben Gamari at 2020-01-20T15:33:28-05:00 testsuite: Preserve more information in framework failures Namely print the entire exception in hopes that this will help track down #17649. - - - - - b62b8cea by Ömer Sinan Ağacan at 2020-01-20T15:34:06-05:00 Remove deprecated -smp flag It was deprecated in 2012 with 46258b40 - - - - - 0c04a86a by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Reenable submodule linter - - - - - 2bfabd22 by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Allow submodule cleaning to fail on Windows Currently CI is inexplicably failing with ``` $ git submodule foreach git clean -xdf fatal: not a git repository: libffi-tarballs/../.git/modules/libffi-tarballs ``` I have no idea how this working tree got into such a state but we do need to fail more gracefully when it happens. Consequently, we allow the cleaning step to fail. - - - - - 14bced99 by Xavier Denis at 2020-01-20T15:35:21-05:00 Put the docs for :instances in alphabetical position - - - - - 7e0bb82b by Ben Gamari at 2020-01-20T15:35:57-05:00 Add missing Note [Improvement from Ground Wanteds] Closes #17659. - - - - - 17e43a7c by Ben Gamari at 2020-01-20T15:36:32-05:00 unregisterised: Fix declaration for stg_NO_FINALIZER Previously it had a redundant _entry suffix. We never noticed this previously presumably because we never generated references to it (however hard to believe this may be). However, it did start failing in !1304. - - - - - 3dae006f by PHO at 2020-01-20T15:37:08-05:00 Avoid ./configure failure on NetBSD - - - - - 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 9d6e30b7 by Sebastian Graf at 2020-04-15T17:05:14+02:00 Nested CPR - - - - - 21 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - + .gitlab/issue_templates/documentation_issue.md - + .gitlab/linters/check-changelogs.sh - .gitlab/linters/check-cpp.py - .gitlab/linters/check-makefiles.py - .gitlab/linters/linter.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/push-test-metrics.sh - + .gitlab/test-metrics.sh - − .gitlab/win32-init.sh - .gitmodules - .mailmap - CODEOWNERS - HACKING.md - aclocal.m4 - boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/389f69e8384389335711bc0c6a59a0adab191535...9d6e30b7541f036e7237e34596431002c6a38fbc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/389f69e8384389335711bc0c6a59a0adab191535...9d6e30b7541f036e7237e34596431002c6a38fbc You're receiving 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 15 15:08:35 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 15 Apr 2020 11:08:35 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 14 commits: StgCRun: Enable unwinding only on Linux Message-ID: <5e97237348545_61677c82e0c51427e5@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 5c07bb7d by Ryan Scott at 2020-04-15T11:08:22-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - a5fddb24 by Daniel Gröber at 2020-04-15T11:08:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 28 changed files: - compiler/GHC/Core/Ppr.hs - compiler/GHC/Tc/Module.hs - compiler/ghc.cabal.in - ghc.mk - hadrian/src/Settings/Builders/Ghc.hs - includes/rts/storage/ClosureMacros.h - includes/rts/storage/GC.h - libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc - libraries/exceptions - libraries/ghci/ghci.cabal.in - libraries/template-haskell/template-haskell.cabal.in - libraries/text - rts/Apply.cmm - rts/LdvProfile.c - rts/PrimOps.cmm - rts/ProfHeap.c - rts/StgCRun.c - rts/sm/Evac.c - rts/sm/Sanity.c - rts/sm/Storage.c - + testsuite/tests/ghci/should_fail/T18052b.script - + testsuite/tests/ghci/should_fail/T18052b.stderr - testsuite/tests/ghci/should_fail/all.T - testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr - + testsuite/tests/printer/T18052a.hs - + testsuite/tests/printer/T18052a.stderr - testsuite/tests/printer/all.T - utils/ghc-cabal/ghc.mk Changes: ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -123,11 +123,13 @@ ppr_binding ann (val_bdr, expr) , pp_bind ] where + pp_val_bdr = pprPrefixOcc val_bdr + pp_bind = case bndrIsJoin_maybe val_bdr of Nothing -> pp_normal_bind Just ar -> pp_join_bind ar - pp_normal_bind = hang (ppr val_bdr) 2 (equals <+> pprCoreExpr expr) + pp_normal_bind = hang pp_val_bdr 2 (equals <+> pprCoreExpr expr) -- For a join point of join arity n, we want to print j = \x1 ... xn -> e -- as "j x1 ... xn = e" to differentiate when a join point returns a @@ -135,7 +137,7 @@ ppr_binding ann (val_bdr, expr) -- an n-argument function). pp_join_bind join_arity | bndrs `lengthAtLeast` join_arity - = hang (ppr val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) + = hang (pp_val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) 2 (equals <+> pprCoreExpr rhs) | otherwise -- Yikes! A join-binding with too few lambda -- Lint will complain, but we don't want to crash @@ -164,8 +166,10 @@ ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc -- an atomic value (e.g. function args) ppr_expr add_par (Var name) - | isJoinId name = add_par ((text "jump") <+> ppr name) - | otherwise = ppr name + | isJoinId name = add_par ((text "jump") <+> pp_name) + | otherwise = pp_name + where + pp_name = pprPrefixOcc name ppr_expr add_par (Type ty) = add_par (text "TYPE:" <+> ppr ty) -- Weird ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> ppr co) ppr_expr add_par (Lit lit) = pprLiteral add_par lit @@ -429,7 +433,7 @@ pprKindedTyVarBndr tyvar -- pprIdBndr does *not* print the type -- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness pprIdBndr :: Id -> SDoc -pprIdBndr id = ppr id <+> pprIdBndrInfo (idInfo id) +pprIdBndr id = pprPrefixOcc id <+> pprIdBndrInfo (idInfo id) pprIdBndrInfo :: IdInfo -> SDoc pprIdBndrInfo info ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2122,7 +2122,7 @@ tcRnStmt hsc_env rdr_stmt } where bad_unboxed id = addErr (sep [text "GHCi can't bind a variable of unlifted type:", - nest 2 (ppr id <+> dcolon <+> ppr (idType id))]) + nest 2 (pprPrefixOcc id <+> dcolon <+> ppr (idType id))]) {- -------------------------------------------------------------------------- @@ -2903,7 +2903,7 @@ ppr_types debug type_env -- etc are suppressed (unless -dppr-debug), -- because they appear elsewhere - ppr_sig id = hang (ppr id <+> dcolon) 2 (ppr (tidyTopType (idType id))) + ppr_sig id = hang (pprPrefixOcc id <+> dcolon) 2 (ppr (tidyTopType (idType id))) ppr_tycons :: Bool -> [FamInst] -> TypeEnv -> SDoc ppr_tycons debug fam_insts type_env @@ -2921,7 +2921,7 @@ ppr_tycons debug fam_insts type_env | otherwise = isExternalName (tyConName tycon) && not (tycon `elem` fi_tycons) ppr_tc tc - = vcat [ hang (ppr (tyConFlavour tc) <+> ppr tc + = vcat [ hang (ppr (tyConFlavour tc) <+> pprPrefixOcc (tyConName tc) <> braces (ppr (tyConArity tc)) <+> dcolon) 2 (ppr (tidyTopType (tyConKind tc))) , nest 2 $ @@ -2955,7 +2955,7 @@ ppr_patsyns type_env = ppr_things "PATTERN SYNONYMS" ppr_ps (typeEnvPatSyns type_env) where - ppr_ps ps = ppr ps <+> dcolon <+> pprPatSynType ps + ppr_ps ps = pprPrefixOcc ps <+> dcolon <+> pprPatSynType ps ppr_insts :: [ClsInst] -> SDoc ppr_insts ispecs ===================================== compiler/ghc.cabal.in ===================================== @@ -69,7 +69,7 @@ Library containers >= 0.5 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, - template-haskell == 2.16.*, + template-haskell == 2.17.*, hpc == 0.6.*, transformers == 0.5.*, ghc-boot == @ProjectVersionMunged@, ===================================== ghc.mk ===================================== @@ -413,8 +413,8 @@ else # CLEANING # Packages that are built by stage0. These packages are dependencies of # programs such as GHC and ghc-pkg, that we do not assume the stage0 # compiler already has installed (or up-to-date enough). - -PACKAGES_STAGE0 = binary text transformers mtl parsec Cabal/Cabal hpc ghc-boot-th ghc-boot template-haskell ghc-heap ghci +# Note that these must be given in topological order. +PACKAGES_STAGE0 = binary transformers mtl hpc ghc-boot-th ghc-boot template-haskell text parsec Cabal/Cabal ghc-heap ghci ifeq "$(Windows_Host)" "NO" PACKAGES_STAGE0 += terminfo endif @@ -441,14 +441,14 @@ PACKAGES_STAGE1 += process PACKAGES_STAGE1 += hpc PACKAGES_STAGE1 += pretty PACKAGES_STAGE1 += binary -PACKAGES_STAGE1 += text PACKAGES_STAGE1 += transformers PACKAGES_STAGE1 += mtl -PACKAGES_STAGE1 += parsec -PACKAGES_STAGE1 += Cabal/Cabal PACKAGES_STAGE1 += ghc-boot-th PACKAGES_STAGE1 += ghc-boot PACKAGES_STAGE1 += template-haskell +PACKAGES_STAGE1 += text +PACKAGES_STAGE1 += parsec +PACKAGES_STAGE1 += Cabal/Cabal PACKAGES_STAGE1 += ghc-compact PACKAGES_STAGE1 += ghc-heap ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -11,6 +11,7 @@ import Settings.Builders.Common import Settings.Warnings import qualified Context as Context import Rules.Libffi (libffiName) +import System.Directory ghcBuilderArgs :: Args ghcBuilderArgs = mconcat [ compileAndLinkHs, compileC, findHsDependencies @@ -215,18 +216,20 @@ packageGhcArgs = do includeGhcArgs :: Args includeGhcArgs = do pkg <- getPackage - path <- getBuildPath + path <- exprIO . makeAbsolute =<< getBuildPath context <- getContext srcDirs <- getContextData srcDirs - autogen <- expr $ autogenPath context + abSrcDirs <- exprIO $ mapM makeAbsolute [ (pkgPath pkg -/- dir) | dir <- srcDirs ] + autogen <- expr (autogenPath context) + cautogen <- exprIO (makeAbsolute autogen) stage <- getStage - libPath <- expr $ stageLibPath stage + libPath <- expr (stageLibPath stage) let cabalMacros = autogen -/- "cabal_macros.h" expr $ need [cabalMacros] mconcat [ arg "-i" , arg $ "-i" ++ path - , arg $ "-i" ++ autogen - , pure [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ] + , arg $ "-i" ++ cautogen + , pure [ "-i" ++ d | d <- abSrcDirs ] , cIncludeArgs , arg $ "-I" ++ libPath , arg $ "-optc-I" ++ libPath ===================================== includes/rts/storage/ClosureMacros.h ===================================== @@ -474,31 +474,39 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) OVERWRITING_CLOSURE(p) on the old closure that is about to be overwritten. - Note [zeroing slop] + Note [zeroing slop when overwriting closures] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - In some scenarios we write zero words into "slop"; memory that is - left unoccupied after we overwrite a closure in the heap with a - smaller closure. + When we overwrite a closure in the heap with a smaller one, in some scenarios + we need to write zero words into "slop"; the memory that is left + unoccupied. See Note [slop on the heap] Zeroing slop is required for: - - full-heap sanity checks (DEBUG, and +RTS -DS) - - LDV profiling (PROFILING, and +RTS -hb) + - full-heap sanity checks (DEBUG, and +RTS -DS), - Zeroing slop must be disabled for: + - LDV profiling (PROFILING, and +RTS -hb) and - - THREADED_RTS with +RTS -N2 and greater, because we cannot - overwrite slop when another thread might be reading it. + However we can get into trouble if we're zeroing slop for ordinarily + immutable closures when using multiple threads, since there is nothing + preventing another thread from still being in the process of reading the + memory we're about to zero. - Hence, slop is zeroed when either: + Thus, with the THREADED RTS and +RTS -N2 or greater we must not zero + immutable closure's slop. - - PROFILING && era <= 0 (LDV is on) - - !THREADED_RTS && DEBUG + Hence, an immutable closure's slop is zeroed when either: - And additionally: + - PROFILING && era > 0 (LDV is on) or + - !THREADED && DEBUG - - LDV profiling and +RTS -N2 are incompatible - - full-heap sanity checks are disabled for THREADED_RTS + Additionally: + + - LDV profiling and +RTS -N2 are incompatible, + + - full-heap sanity checks are disabled for the THREADED RTS, at least when + they don't run right after GC when there is no slop. + See Note [heap sanity checking with SMP]. -------------------------------------------------------------------------- */ @@ -524,23 +532,24 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) #if defined(PROFILING) void LDV_recordDead (const StgClosure *c, uint32_t size); +RTS_PRIVATE bool isInherentlyUsed ( StgHalfWord closure_type ); #endif EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset /* in words */, uint32_t size /* closure size, in words */, - bool prim /* Whether to call LDV_recordDead */ + bool inherently_used USED_IF_PROFILING ); -EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size, bool prim USED_IF_PROFILING) +EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size, bool inherently_used USED_IF_PROFILING) { #if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK - // see Note [zeroing slop], also #8402 + // see Note [zeroing slop when overwriting closures], also #8402 if (era <= 0) return; #endif // For LDV profiling, we need to record the closure as dead #if defined(PROFILING) - if (!prim) { LDV_recordDead(p, size); }; + if (!inherently_used) { LDV_recordDead(p, size); }; #endif for (uint32_t i = offset; i < size; i++) { @@ -551,7 +560,11 @@ EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t EXTERN_INLINE void overwritingClosure (StgClosure *p); EXTERN_INLINE void overwritingClosure (StgClosure *p) { - overwritingClosure_(p, sizeofW(StgThunkHeader), closure_sizeW(p), false); +#if defined(PROFILING) + ASSERT(!isInherentlyUsed(get_itbl(p)->type)); +#endif + overwritingClosure_(p, sizeofW(StgThunkHeader), closure_sizeW(p), + /*inherently_used=*/false); } // Version of 'overwritingClosure' which overwrites only a suffix of a @@ -564,21 +577,24 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p) EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset); EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset) { - // Set prim = true because overwritingClosureOfs is only - // ever called by - // shrinkMutableByteArray# (ARR_WORDS) - // shrinkSmallMutableArray# (SMALL_MUT_ARR_PTRS) - // This causes LDV_recordDead to be invoked. We want this - // to happen because the implementations of the above - // primops both call LDV_RECORD_CREATE after calling this, - // effectively replacing the LDV closure biography. - // See Note [LDV Profiling when Shrinking Arrays] - overwritingClosure_(p, offset, closure_sizeW(p), true); + // Since overwritingClosureOfs is only ever called by: + // + // - shrinkMutableByteArray# (ARR_WORDS) and + // + // - shrinkSmallMutableArray# (SMALL_MUT_ARR_PTRS) + // + // we can safely set inherently_used = true, which means LDV_recordDead + // won't be invoked below. Since these closures are inherenlty used we don't + // need to track their destruction. + overwritingClosure_(p, offset, closure_sizeW(p), /*inherently_used=*/true); } // Version of 'overwritingClosure' which takes closure size as argument. EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size /* in words */); EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size) { - overwritingClosure_(p, sizeofW(StgThunkHeader), size, false); +#if defined(PROFILING) + ASSERT(!isInherentlyUsed(get_itbl(p)->type)); +#endif + overwritingClosure_(p, sizeofW(StgThunkHeader), size, /*inherently_used=*/false); } ===================================== includes/rts/storage/GC.h ===================================== @@ -170,10 +170,13 @@ extern generation * oldest_gen; Allocates memory from the nursery in the current Capability. - StgPtr allocatePinned(Capability *cap, W_ n) + StgPtr allocatePinned(Capability *cap, W_ n, W_ alignment, W_ align_off) Allocates a chunk of contiguous store n words long, which is at a fixed - address (won't be moved by GC). + address (won't be moved by GC). The + word at the byte offset 'align_off' + will be aligned to 'alignment', which + must be a power of two. Returns a pointer to the first word. Always succeeds. @@ -191,7 +194,7 @@ extern generation * oldest_gen; StgPtr allocate ( Capability *cap, W_ n ); StgPtr allocateMightFail ( Capability *cap, W_ n ); -StgPtr allocatePinned ( Capability *cap, W_ n ); +StgPtr allocatePinned ( Capability *cap, W_ n, W_ alignment, W_ align_off); /* memory allocator for executable memory */ typedef void* AdjustorWritable; ===================================== libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc ===================================== @@ -12,6 +12,9 @@ module GHC.IO.Handle.Lock.LinuxOFD where import GHC.Base () -- Make implicit dependency known to build system #else +-- Not only is this a good idea but it also works around #17950. +#define _FILE_OFFSET_BITS 64 + #include #include ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit 0a1f9ff0f407da360fc9405a07d5d06d28e6c077 +Subproject commit fe4166f8d23d8288ef2cbbf9e36118b6b99e0d7d ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -81,7 +81,7 @@ library ghc-boot == @ProjectVersionMunged@, ghc-boot-th == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, - template-haskell == 2.16.*, + template-haskell == 2.17.*, transformers == 0.5.* if !os(windows) ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -3,7 +3,7 @@ -- template-haskell.cabal. name: template-haskell -version: 2.16.0.0 +version: 2.17.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit 1127b30e1e0affa08f056e35ad17957b12982ba3 +Subproject commit a01843250166b5559936ba5eb81f7873e709587a ===================================== rts/Apply.cmm ===================================== @@ -689,7 +689,7 @@ for: // Because of eager blackholing the closure no longer has correct size so // threadPaused() can't correctly zero the slop, so we do it here. See #15571 - // and Note [zeroing slop]. + // and Note [zeroing slop when overwriting closures]. OVERWRITING_CLOSURE_SIZE(ap, BYTES_TO_WDS(SIZEOF_StgThunkHeader) + 2 + Words); ENTER_R1(); ===================================== rts/LdvProfile.c ===================================== @@ -18,6 +18,37 @@ #include "RtsUtils.h" #include "Schedule.h" +bool isInherentlyUsed( StgHalfWord closure_type ) +{ + switch(closure_type) { + case TSO: + case STACK: + case MVAR_CLEAN: + case MVAR_DIRTY: + case TVAR: + case MUT_ARR_PTRS_CLEAN: + case MUT_ARR_PTRS_DIRTY: + case MUT_ARR_PTRS_FROZEN_CLEAN: + case MUT_ARR_PTRS_FROZEN_DIRTY: + case SMALL_MUT_ARR_PTRS_CLEAN: + case SMALL_MUT_ARR_PTRS_DIRTY: + case SMALL_MUT_ARR_PTRS_FROZEN_CLEAN: + case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: + case ARR_WORDS: + case WEAK: + case MUT_VAR_CLEAN: + case MUT_VAR_DIRTY: + case BCO: + case PRIM: + case MUT_PRIM: + case TREC_CHUNK: + return true; + + default: + return false; + } +} + /* -------------------------------------------------------------------------- * This function is called eventually on every object destroyed during * a garbage collection, whether it is a major garbage collection or @@ -55,33 +86,13 @@ processHeapClosureForDead( const StgClosure *c ) size = closure_sizeW(c); - switch (info->type) { - /* + /* 'inherently used' cases: do nothing. - */ - case TSO: - case STACK: - case MVAR_CLEAN: - case MVAR_DIRTY: - case TVAR: - case MUT_ARR_PTRS_CLEAN: - case MUT_ARR_PTRS_DIRTY: - case MUT_ARR_PTRS_FROZEN_CLEAN: - case MUT_ARR_PTRS_FROZEN_DIRTY: - case SMALL_MUT_ARR_PTRS_CLEAN: - case SMALL_MUT_ARR_PTRS_DIRTY: - case SMALL_MUT_ARR_PTRS_FROZEN_CLEAN: - case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: - case ARR_WORDS: - case WEAK: - case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: - case BCO: - case PRIM: - case MUT_PRIM: - case TREC_CHUNK: + */ + if(isInherentlyUsed(info->type)) return size; + switch (info->type) { /* ordinary cases: call LDV_recordDead(). */ ===================================== rts/PrimOps.cmm ===================================== @@ -89,22 +89,15 @@ stg_newPinnedByteArrayzh ( W_ n ) /* When we actually allocate memory, we need to allow space for the header: */ bytes = bytes + SIZEOF_StgArrBytes; - /* And we want to align to BA_ALIGN bytes, so we need to allow space - to shift up to BA_ALIGN - 1 bytes: */ - bytes = bytes + BA_ALIGN - 1; /* Now we convert to a number of words: */ words = ROUNDUP_BYTES_TO_WDS(bytes); - ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words); + ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words, BA_ALIGN, SIZEOF_StgArrBytes); if (p == NULL) { jump stg_raisezh(base_GHCziIOziException_heapOverflow_closure); } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - /* Now we need to move p forward so that the payload is aligned - to BA_ALIGN bytes: */ - p = p + ((-p - SIZEOF_StgArrBytes) & BA_MASK); - /* No write barrier needed since this is a new allocation. */ SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; @@ -121,7 +114,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment ) /* we always supply at least word-aligned memory, so there's no need to allow extra space for alignment if the requirement is less than a word. This also prevents mischief with alignment == 0. */ - if (alignment <= SIZEOF_W) { alignment = 1; } + if (alignment <= SIZEOF_W) { alignment = SIZEOF_W; } bytes = n; @@ -131,23 +124,15 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment ) /* When we actually allocate memory, we need to allow space for the header: */ bytes = bytes + SIZEOF_StgArrBytes; - /* And we want to align to bytes, so we need to allow space - to shift up to bytes: */ - bytes = bytes + alignment - 1; /* Now we convert to a number of words: */ words = ROUNDUP_BYTES_TO_WDS(bytes); - ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words); + ("ptr" p) = ccall allocatePinned(MyCapability() "ptr", words, alignment, SIZEOF_StgArrBytes); if (p == NULL) { jump stg_raisezh(base_GHCziIOziException_heapOverflow_closure); } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - /* Now we need to move p forward so that the payload is aligned - to bytes. Note that we are assuming that - is a power of 2, which is technically not guaranteed */ - p = p + ((-p - SIZEOF_StgArrBytes) & (alignment - 1)); - /* No write barrier needed since this is a new allocation. */ SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; @@ -173,6 +158,17 @@ stg_isMutableByteArrayPinnedzh ( gcptr mba ) jump stg_isByteArrayPinnedzh(mba); } +/* Note [LDV profiling and resizing arrays] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * As far as the LDV profiler is concerned arrays are "inherently used" which + * means we don't track their time of use and eventual destruction. We just + * assume they get used. + * + * Thus it is not necessary to call LDV_RECORD_CREATE when resizing them as we + * used to as the LDV profiler will essentially ignore arrays anyways. + */ + // shrink size of MutableByteArray in-place stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size ) // MutableByteArray# s -> Int# -> State# s -> State# s @@ -182,9 +178,7 @@ stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) + ROUNDUP_BYTES_TO_WDS(new_size))); StgArrBytes_bytes(mba) = new_size; - // See the comments in overwritingClosureOfs for an explanation - // of the interaction with LDV profiling. - LDV_RECORD_CREATE(mba); + // No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays] return (); } @@ -208,7 +202,7 @@ stg_resizzeMutableByteArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) + new_size_wds)); StgArrBytes_bytes(mba) = new_size; - LDV_RECORD_CREATE(mba); + // No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays] return (mba); } else { @@ -237,9 +231,7 @@ stg_shrinkSmallMutableArrayzh ( gcptr mba, W_ new_size ) OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) + new_size)); StgSmallMutArrPtrs_ptrs(mba) = new_size; - // See the comments in overwritingClosureOfs for an explanation - // of the interaction with LDV profiling. - LDV_RECORD_CREATE(mba); + // No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays] return (); } ===================================== rts/ProfHeap.c ===================================== @@ -280,6 +280,8 @@ LDV_recordDead( const StgClosure *c, uint32_t size ) uint32_t t; counter *ctr; + ASSERT(!isInherentlyUsed(get_itbl(c)->type)); + if (era > 0 && closureSatisfiesConstraints(c)) { size -= sizeofW(StgProfHeader); ASSERT(LDVW(c) != 0); @@ -550,8 +552,6 @@ initHeapProfiling(void) void endHeapProfiling(void) { - StgDouble seconds; - if (! RtsFlags.ProfFlags.doHeapProfile) { return; } @@ -594,7 +594,10 @@ endHeapProfiling(void) stgFree(censuses); - seconds = mut_user_time(); + RTSStats stats; + getRTSStats(&stats); + Time mut_time = stats.mutator_cpu_ns; + StgDouble seconds = TimeToSecondsDbl(mut_time); printSample(true, seconds); printSample(false, seconds); fclose(hp_file); @@ -1275,8 +1278,22 @@ heapCensusChain( Census *census, bdescr *bd ) heapProfObject(census,(StgClosure*)p,size,prim); p += size; - /* skip over slop */ - while (p < bd->free && !*p) p++; // skip slop + + /* skip over slop, see Note [slop on the heap] */ + while (p < bd->free && !*p) p++; + /* Note [skipping slop in the heap profiler] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * We make sure to zero slop that can remain after a major GC so + * here we can assume any slop words we see until the block's free + * pointer are zero. Since info pointers are always nonzero we can + * use this to scan for the next valid heap closure. + * + * Note that not all types of slop are relevant here, only the ones + * that can reman after major GC. So essentially just large objects + * and pinned objects. All other closures will have been packed nice + * and thight into fresh blocks. + */ } } } ===================================== rts/StgCRun.c ===================================== @@ -29,6 +29,13 @@ #include "PosixSource.h" #include "ghcconfig.h" +// Enable DWARF Call-Frame Information (used for stack unwinding) on Linux. +// This is not supported on Darwin and SmartOS due to assembler differences +// (#15207). +#if defined(linux_HOST_OS) +#define ENABLE_UNWINDING +#endif + #if defined(sparc_HOST_ARCH) || defined(USE_MINIINTERPRETER) /* include Stg.h first because we want real machine regs in here: we * have to get the value of R1 back from Stg land to C land intact. @@ -405,7 +412,7 @@ StgRunIsImplementedInAssembler(void) "movq %%xmm15,136(%%rax)\n\t" #endif -#if !defined(darwin_HOST_OS) +#if defined(ENABLE_UNWINDING) /* * Let the unwinder know where we saved the registers * See Note [Unwinding foreign exports on x86-64]. @@ -444,7 +451,7 @@ StgRunIsImplementedInAssembler(void) #error "RSP_DELTA too big" #endif "\n\t" -#endif /* !defined(darwin_HOST_OS) */ +#endif /* defined(ENABLE_UNWINDING) */ /* * Set BaseReg @@ -519,7 +526,7 @@ StgRunIsImplementedInAssembler(void) "i"(RESERVED_C_STACK_BYTES + STG_RUN_STACK_FRAME_SIZE /* rip relative to cfa */) -#if !defined(darwin_HOST_OS) +#if defined(ENABLE_UNWINDING) , "i"((RSP_DELTA & 127) | (128 * ((RSP_DELTA >> 7) > 0))) /* signed LEB128-encoded delta from rsp - byte 1 */ #if (RSP_DELTA >> 7) > 0 @@ -538,7 +545,7 @@ StgRunIsImplementedInAssembler(void) #endif #undef RSP_DELTA -#endif /* !defined(darwin_HOST_OS) */ +#endif /* defined(ENABLE_UNWINDING) */ ); /* ===================================== rts/sm/Evac.c ===================================== @@ -298,7 +298,7 @@ copy(StgClosure **p, const StgInfoTable *info, that has been evacuated, or unset otherwise. -------------------------------------------------------------------------- */ -STATIC_INLINE void +static void evacuate_large(StgPtr p) { bdescr *bd; ===================================== rts/sm/Sanity.c ===================================== @@ -475,7 +475,7 @@ void checkHeapChain (bdescr *bd) ASSERT( size >= MIN_PAYLOAD_SIZE + sizeofW(StgHeader) ); p += size; - /* skip over slop */ + /* skip over slop, see Note [slop on the heap] */ while (p < bd->free && (*p < 0x1000 || !LOOKS_LIKE_INFO_PTR(*p))) { p++; } } @@ -796,12 +796,17 @@ static void checkGeneration (generation *gen, ASSERT(countBlocks(gen->large_objects) == gen->n_large_blocks); #if defined(THREADED_RTS) + // Note [heap sanity checking with SMP] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // heap sanity checking doesn't work with SMP for two reasons: - // * we can't zero the slop (see Updates.h). However, we can sanity-check - // the heap after a major gc, because there is no slop. // - // * the nonmoving collector may be mutating its large object lists, unless we - // were in fact called by the nonmoving collector. + // * We can't zero the slop. However, we can sanity-check the heap after a + // major gc, because there is no slop. See also Updates.h and Note + // [zeroing slop when overwriting closures]. + // + // * The nonmoving collector may be mutating its large object lists, + // unless we were in fact called by the nonmoving collector. if (!after_major_gc) return; #endif ===================================== rts/sm/Storage.c ===================================== @@ -907,6 +907,54 @@ accountAllocation(Capability *cap, W_ n) } +/* Note [slop on the heap] + * ~~~~~~~~~~~~~~~~~~~~~~~ + * + * We use the term "slop" to refer to allocated memory on the heap which isn't + * occupied by any closure. Usually closures are packet tightly into the heap + * blocks, storage for one immediately following another. However there are + * situations where slop is left behind: + * + * - Allocating large objects (BF_LARGE) + * + * These are given an entire block, but if they don't fill the entire block + * the rest is slop. See allocateMightFail in Storage.c. + * + * - Allocating pinned objects with alignment (BF_PINNED) + * + * These are packet into blocks like normal closures, however they + * can have alignment constraints and any memory that needed to be skipped for + * alignment becomes slop. See allocatePinned in Storage.c. + * + * - Shrinking (Small)Mutable(Byte)Array# + * + * The size of these closures can be decreased after allocation, leaving any, + * now unused memory, behind as slop. See stg_resizzeMutableByteArrayzh, + * stg_shrinkSmallMutableArrayzh, and stg_shrinkMutableByteArrayzh in + * PrimOps.cmm. + * + * This type of slop is extra tricky because it can also be pinned and + * large. + * + * - Overwriting closures + * + * During GC the RTS overwrites closures with forwarding pointers, this can + * leave slop behind depending on the size of the closure being + * overwritten. See Note [zeroing slop when overwriting closures]. + * + * Under various ways we actually zero slop so we can linearly scan over blocks + * of closures. This trick is used by the sanity checking code and the heap + * profiler, see Note [skipping slop in the heap profiler]. + * + * When profiling we zero: + * - Pinned object alignment slop, see MEMSET_IF_PROFILING_W in allocatePinned. + * - Shrunk array slop, see OVERWRITING_MUTABLE_CLOSURE. + * + * When performing LDV profiling or using a (single threaded) debug RTS we zero + * slop even when overwriting immutable closures, see Note [zeroing slop when + * overwriting closures]. + */ + /* ----------------------------------------------------------------------------- StgPtr allocate (Capability *cap, W_ n) @@ -1059,6 +1107,26 @@ allocateMightFail (Capability *cap, W_ n) return p; } +/** + * Calculate the number of words we need to add to 'p' so it satisfies the + * alignment constraint '(p + off) & (align-1) == 0'. + */ +#define ALIGN_WITH_OFF_W(p, align, off) \ + (((-((uintptr_t)p) - off) & (align-1)) / sizeof(W_)) + +/** + * When profiling we zero the space used for alignment. This allows us to + * traverse pinned blocks in the heap profiler. + * + * See Note [skipping slop in the heap profiler] + */ +#if defined(PROFILING) +#define MEMSET_IF_PROFILING_W(p, val, len_w) memset(p, val, (len_w) * sizeof(W_)) +#else +#define MEMSET_IF_PROFILING_W(p, val, len_w) \ + do { (void)(p); (void)(val); (void)(len_w); } while(0) +#endif + /* --------------------------------------------------------------------------- Allocate a fixed/pinned object. @@ -1084,29 +1152,49 @@ allocateMightFail (Capability *cap, W_ n) ------------------------------------------------------------------------- */ StgPtr -allocatePinned (Capability *cap, W_ n) +allocatePinned (Capability *cap, W_ n /*words*/, W_ alignment /*bytes*/, W_ align_off /*bytes*/) { StgPtr p; bdescr *bd; + // Alignment and offset have to be a power of two + ASSERT(alignment && !(alignment & (alignment - 1))); + ASSERT(alignment >= sizeof(W_)); + + ASSERT(!(align_off & (align_off - 1))); + + const StgWord alignment_w = alignment / sizeof(W_); + // If the request is for a large object, then allocate() // will give us a pinned object anyway. if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) { - p = allocateMightFail(cap, n); + // For large objects we don't bother optimizing the number of words + // allocated for alignment reasons. Here we just allocate the maximum + // number of extra words we could possibly need to satisfy the alignment + // constraint. + p = allocateMightFail(cap, n + alignment_w - 1); if (p == NULL) { return NULL; } else { Bdescr(p)->flags |= BF_PINNED; + W_ off_w = ALIGN_WITH_OFF_W(p, alignment, align_off); + MEMSET_IF_PROFILING_W(p, 0, off_w); + p += off_w; + MEMSET_IF_PROFILING_W(p + n, 0, alignment_w - off_w - 1); return p; } } - accountAllocation(cap, n); bd = cap->pinned_object_block; + W_ off_w = 0; + + if(bd) + off_w = ALIGN_WITH_OFF_W(bd->free, alignment, align_off); + // If we don't have a block of pinned objects yet, or the current // one isn't large enough to hold the new object, get a new one. - if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) { + if (bd == NULL || (bd->free + off_w + n) > (bd->start + BLOCK_SIZE_W)) { // stash the old block on cap->pinned_object_blocks. On the // next GC cycle these objects will be moved to @@ -1158,10 +1246,20 @@ allocatePinned (Capability *cap, W_ n) // the next GC the BF_EVACUATED flag will be cleared, and the // block will be promoted as usual (if anything in it is // live). + + off_w = ALIGN_WITH_OFF_W(bd->free, alignment, align_off); } p = bd->free; + + MEMSET_IF_PROFILING_W(p, 0, off_w); + + n += off_w; + p += off_w; bd->free += n; + + accountAllocation(cap, n); + return p; } ===================================== testsuite/tests/ghci/should_fail/T18052b.script ===================================== @@ -0,0 +1,2 @@ +:set -XMagicHash +let (%%%) = 1# ===================================== testsuite/tests/ghci/should_fail/T18052b.stderr ===================================== @@ -0,0 +1,3 @@ + +:1:1: error: + GHCi can't bind a variable of unlifted type: (%%%) :: GHC.Prim.Int# ===================================== testsuite/tests/ghci/should_fail/all.T ===================================== @@ -3,3 +3,4 @@ test('T10549a', [], ghci_script, ['T10549a.script']) test('T15055', normalise_version('ghc'), ghci_script, ['T15055.script']) test('T16013', [], ghci_script, ['T16013.script']) test('T16287', [], ghci_script, ['T16287.script']) +test('T18052b', [], ghci_script, ['T18052b.script']) ===================================== testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr ===================================== @@ -1,28 +1,28 @@ TYPE SIGNATURES - !! :: forall {a}. [a] -> Int -> a - $ :: forall {a} {b}. (a -> b) -> a -> b - $! :: forall {a} {b}. (a -> b) -> a -> b - && :: Bool -> Bool -> Bool - * :: forall {a}. Num a => a -> a -> a - ** :: forall {a}. Floating a => a -> a -> a - + :: forall {a}. Num a => a -> a -> a - ++ :: forall {a}. [a] -> [a] -> [a] - - :: forall {a}. Num a => a -> a -> a - . :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c - / :: forall {a}. Fractional a => a -> a -> a - /= :: forall {a}. Eq a => a -> a -> Bool - < :: forall {a}. Ord a => a -> a -> Bool - <= :: forall {a}. Ord a => a -> a -> Bool - =<< :: + (!!) :: forall {a}. [a] -> Int -> a + ($) :: forall {a} {b}. (a -> b) -> a -> b + ($!) :: forall {a} {b}. (a -> b) -> a -> b + (&&) :: Bool -> Bool -> Bool + (*) :: forall {a}. Num a => a -> a -> a + (**) :: forall {a}. Floating a => a -> a -> a + (+) :: forall {a}. Num a => a -> a -> a + (++) :: forall {a}. [a] -> [a] -> [a] + (-) :: forall {a}. Num a => a -> a -> a + (.) :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c + (/) :: forall {a}. Fractional a => a -> a -> a + (/=) :: forall {a}. Eq a => a -> a -> Bool + (<) :: forall {a}. Ord a => a -> a -> Bool + (<=) :: forall {a}. Ord a => a -> a -> Bool + (=<<) :: forall {m :: * -> *} {a} {b}. Monad m => (a -> m b) -> m a -> m b - == :: forall {a}. Eq a => a -> a -> Bool - > :: forall {a}. Ord a => a -> a -> Bool - >= :: forall {a}. Ord a => a -> a -> Bool - >> :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b - >>= :: + (==) :: forall {a}. Eq a => a -> a -> Bool + (>) :: forall {a}. Ord a => a -> a -> Bool + (>=) :: forall {a}. Ord a => a -> a -> Bool + (>>) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b + (>>=) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> (a -> m b) -> m b - ^ :: forall {b} {a}. (Integral b, Num a) => a -> b -> a - ^^ :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a + (^) :: forall {b} {a}. (Integral b, Num a) => a -> b -> a + (^^) :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a abs :: forall {a}. Num a => a -> a acos :: forall {a}. Floating a => a -> a acosh :: forall {a}. Floating a => a -> a @@ -234,7 +234,7 @@ TYPE SIGNATURES zipWith3 :: forall {a} {b} {c} {d}. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] - || :: Bool -> Bool -> Bool + (||) :: Bool -> Bool -> Bool Dependent modules: [] -Dependent packages: [base-4.13.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeOperators #-} +module T18052a where + +(+++) = (++) +pattern x :||: y = (x,y) +type (^^^) = Either +data (&&&) ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -0,0 +1,42 @@ +TYPE SIGNATURES + (+++) :: forall {a}. [a] -> [a] -> [a] +TYPE CONSTRUCTORS + data type (&&&){0} :: * + type synonym (^^^){0} :: * -> * -> * +PATTERN SYNONYMS + (:||:) :: forall {a} {b}. a -> b -> (a, b) +Dependent modules: [] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 18, types: 53, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) +[GblId, Arity=2, Unf=OtherCon []] +T18052a.$b:||: = GHC.Tuple.(,) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +(+++) :: forall {a}. [a] -> [a] -> [a] +[GblId] +(+++) = (++) + +-- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +T18052a.$m:||: + :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. + (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r +[GblId, Arity=3, Unf=OtherCon []] +T18052a.$m:||: + = \ (@(rep :: GHC.Types.RuntimeRep)) + (@(r :: TYPE rep)) + (@a) + (@b) + (scrut :: (a, b)) + (cont :: a -> b -> r) + _ [Occ=Dead] -> + case scrut of { (x, y) -> cont x y } + + + ===================================== testsuite/tests/printer/all.T ===================================== @@ -57,3 +57,5 @@ test('T14306', ignore_stderr, makefile_test, ['T14306']) test('T14343', normal, compile_fail, ['']) test('T14343b', normal, compile_fail, ['']) test('T15761', normal, compile_fail, ['']) +test('T18052a', normal, compile, + ['-ddump-simpl -ddump-types -dno-typeable-binds -dsuppress-uniques']) ===================================== utils/ghc-cabal/ghc.mk ===================================== @@ -23,9 +23,9 @@ CABAL_CONSTRAINT := --constraint="Cabal == $(CABAL_DOTTED_VERSION)" # macros is triggered by `-hide-all-packages`, so we have to explicitly # enumerate all packages we need in scope. ifeq "$(Windows_Host)" "YES" -CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath Win32 +CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath Win32 template-haskell else -CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath unix +CABAL_BUILD_DEPS := ghc-prim base array transformers time containers bytestring deepseq process pretty directory filepath unix template-haskell endif ghc-cabal_DIST_BINARY_NAME = ghc-cabal$(exeext0) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b48d78d3fa1c4e0b70e9f98478a101fb4dd57ea3...a5fddb249ce819c5d3aa9a33a63e99f8042a0ced -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b48d78d3fa1c4e0b70e9f98478a101fb4dd57ea3...a5fddb249ce819c5d3aa9a33a63e99f8042a0ced You're receiving 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 15 15:44:57 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Wed, 15 Apr 2020 11:44:57 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e972bf988571_6167134ebbc45152249@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: b18aef96 by John Ericson at 2020-04-15T11:43:59-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -23,8 +23,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +62,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +73,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +173,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +244,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +277,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +304,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +326,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +526,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +562,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +577,35 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +644,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +729,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +745,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +762,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +783,12 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +830,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +856,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +868,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +897,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b18aef96db43671ca89087389a4a7cf5c3a2734b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b18aef96db43671ca89087389a4a7cf5c3a2734b You're receiving 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 15 15:45:57 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Wed, 15 Apr 2020 11:45:57 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 13 commits: StgCRun: Enable unwinding only on Linux Message-ID: <5e972c3595671_6167134ebbc451532ab@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - c8175f9a by John Ericson at 2020-04-15T11:45:02-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 30 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/ghc.cabal.in - compiler/parser/RdrHsSyn.hs - ghc.mk - hadrian/src/Settings/Builders/Ghc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b18aef96db43671ca89087389a4a7cf5c3a2734b...c8175f9a4b88b62aa3933e97463f89b5f964d1c7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b18aef96db43671ca89087389a4a7cf5c3a2734b...c8175f9a4b88b62aa3933e97463f89b5f964d1c7 You're receiving 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 15 17:48:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 13:48:08 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] gitlab-ci: Use rules syntax for conditional jobs Message-ID: <5e9748d849336_6167e4e49b451703ae@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: 2615d24e by Ben Gamari at 2020-04-15T13:47:41-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -26,19 +26,18 @@ stages: - testing # head.hackage correctness and compiler performance testing - deploy # push documentation -# N.B.Don't run on wip/ branches, instead on run on merge requests. -.only-default: &only-default - only: - - master - - /ghc-[0-9]+\.[0-9]+/ - - merge_requests - - tags - - web +workflow: + # N.B.Don't run on wip/ branches, instead on run on merge requests. + rules: + - if: $CI_MERGE_REQUEST_ID + - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' + - if: '$CI_PIPELINE_SOURCE == "web"' .nightly: &nightly - only: - variables: - - $NIGHTLY + rules: + - if: $NIGHTLY artifacts: when: always expire_in: 8 weeks @@ -50,9 +49,8 @@ stages: artifacts: when: always expire_in: 1 year - only: - variables: - - $RELEASE == "yes" + rules: + - if: '$RELEASE == "yes"' ############################################################ # Runner Tags @@ -86,13 +84,11 @@ ghc-linters: dependencies: [] tags: - lint - only: - refs: - - merge_requests + rules: + - if: $CI_MERGE_REQUEST_ID # Run mypy Python typechecker on linter scripts. lint-linters: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -103,7 +99,6 @@ lint-linters: # Check that .T files all parse by listing broken tests. lint-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" script: @@ -114,7 +109,6 @@ lint-testsuite: # Run mypy Python typechecker on testsuite driver typecheck-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -127,7 +121,6 @@ typecheck-testsuite: # accommodate, e.g., haddock changes not yet upstream) but not on `master` or # Marge jobs. .lint-submods: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -140,25 +133,14 @@ typecheck-testsuite: tags: - lint -lint-submods-marge: +lint-submods: extends: .lint-submods - only: - refs: - - merge_requests - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" - -lint-submods-mr: - extends: .lint-submods - # Allow failure since any necessary submodule patches may not be upstreamed - # yet. - allow_failure: true - only: - refs: - - merge_requests - except: - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" + # Allow failure on merge requests since any necessary submodule patches may + # not be upstreamed yet. + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' + allow_failure: false + - allow_failure: true lint-submods-branch: extends: .lint-submods @@ -166,13 +148,11 @@ lint-submods-branch: - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - git submodule foreach git remote update - submodchecker . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) - only: - refs: - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' .lint-changelogs: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" dependencies: [] @@ -185,15 +165,13 @@ lint-changelogs: extends: .lint-changelogs # Allow failure since this isn't a final release. allow_failure: true - only: - refs: - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' lint-release-changelogs: extends: .lint-changelogs - only: - refs: - - /ghc-[0-9]+\.[0-9]+\.[0-9]+-.*/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' ############################################################ @@ -201,7 +179,6 @@ lint-release-changelogs: ############################################################ .validate-hadrian: - <<: *only-default variables: FLAVOUR: "validate" script: @@ -250,7 +227,6 @@ validate-x86_64-linux-deb9-unreg-hadrian: TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" hadrian-ghc-in-ghci: - <<: *only-default stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" before_script: @@ -283,7 +259,6 @@ hadrian-ghc-in-ghci: ############################################################ .validate: - <<: *only-default variables: TEST_TYPE: test MAKE_ARGS: "-Werror" @@ -338,9 +313,8 @@ hadrian-ghc-in-ghci: validate-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/ + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/' nightly-x86_64-freebsd: <<: *nightly @@ -417,7 +391,6 @@ validate-x86_64-darwin: # Disabled because of OS X CI capacity .validate-x86_64-darwin-hadrian: - <<: *only-default stage: full-build tags: - x86_64-darwin @@ -780,7 +753,6 @@ validate-x86_64-linux-fedora27: ############################################################ .build-windows: - <<: *only-default # For the reasons given in #17777 this build isn't reliable. allow_failure: true before_script: @@ -954,7 +926,6 @@ nightly-i386-windows: # See Note [Cleanup after shell executor] cleanup-darwin: - <<: *only-default stage: cleanup tags: - x86_64-darwin @@ -976,7 +947,6 @@ cleanup-darwin: ############################################################ doc-tarball: - <<: *only-default stage: packaging tags: - x86_64-linux @@ -1018,8 +988,8 @@ source-tarball: image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" when: always dependencies: [] - only: - - tags + rules: + - if: $CI_COMMIT_TAG artifacts: paths: - ghc-*.tar.xz @@ -1046,7 +1016,6 @@ source-tarball: # pipeline. .hackage: - <<: *only-default stage: testing image: ghcci/x86_64-linux-deb9:0.2 tags: @@ -1063,9 +1032,8 @@ hackage: hackage-label: extends: .hackage - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/ + rules: + if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' nightly-hackage: <<: *nightly @@ -1080,11 +1048,10 @@ perf-nofib: dependencies: - validate-x86_64-linux-deb9-dwarf image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - only: - refs: - - merge_requests - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: $CI_MERGE_REQUEST_ID + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' tags: - x86_64-linux script: @@ -1133,8 +1100,8 @@ pages: EOF - cp -f index.html public/doc - only: - - master + rules: + - if: '$CI_COMMIT_BRANCH == "master"' artifacts: paths: - public View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2615d24ea47b869359dc55772c07df9c09943ed5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2615d24ea47b869359dc55772c07df9c09943ed5 You're receiving 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 15 17:49:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 13:49:13 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] gitlab-ci: Use rules syntax for conditional jobs Message-ID: <5e9749199fadd_6167e4e49b451712bd@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: 15edbb2f by Ben Gamari at 2020-04-15T13:49:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -26,19 +26,18 @@ stages: - testing # head.hackage correctness and compiler performance testing - deploy # push documentation -# N.B.Don't run on wip/ branches, instead on run on merge requests. -.only-default: &only-default - only: - - master - - /ghc-[0-9]+\.[0-9]+/ - - merge_requests - - tags - - web +workflow: + # N.B.Don't run on wip/ branches, instead on run on merge requests. + rules: + - if: $CI_MERGE_REQUEST_ID + - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' + - if: '$CI_PIPELINE_SOURCE == "web"' .nightly: &nightly - only: - variables: - - $NIGHTLY + rules: + - if: $NIGHTLY artifacts: when: always expire_in: 8 weeks @@ -50,9 +49,8 @@ stages: artifacts: when: always expire_in: 1 year - only: - variables: - - $RELEASE == "yes" + rules: + - if: '$RELEASE == "yes"' ############################################################ # Runner Tags @@ -86,13 +84,11 @@ ghc-linters: dependencies: [] tags: - lint - only: - refs: - - merge_requests + rules: + - if: $CI_MERGE_REQUEST_ID # Run mypy Python typechecker on linter scripts. lint-linters: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -103,7 +99,6 @@ lint-linters: # Check that .T files all parse by listing broken tests. lint-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" script: @@ -114,7 +109,6 @@ lint-testsuite: # Run mypy Python typechecker on testsuite driver typecheck-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -127,7 +121,6 @@ typecheck-testsuite: # accommodate, e.g., haddock changes not yet upstream) but not on `master` or # Marge jobs. .lint-submods: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -140,25 +133,14 @@ typecheck-testsuite: tags: - lint -lint-submods-marge: +lint-submods: extends: .lint-submods - only: - refs: - - merge_requests - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" - -lint-submods-mr: - extends: .lint-submods - # Allow failure since any necessary submodule patches may not be upstreamed - # yet. - allow_failure: true - only: - refs: - - merge_requests - except: - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" + # Allow failure on merge requests since any necessary submodule patches may + # not be upstreamed yet. + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' + allow_failure: false + - allow_failure: true lint-submods-branch: extends: .lint-submods @@ -166,13 +148,11 @@ lint-submods-branch: - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - git submodule foreach git remote update - submodchecker . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) - only: - refs: - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' .lint-changelogs: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" dependencies: [] @@ -185,15 +165,13 @@ lint-changelogs: extends: .lint-changelogs # Allow failure since this isn't a final release. allow_failure: true - only: - refs: - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' lint-release-changelogs: extends: .lint-changelogs - only: - refs: - - /ghc-[0-9]+\.[0-9]+\.[0-9]+-.*/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' ############################################################ @@ -201,7 +179,6 @@ lint-release-changelogs: ############################################################ .validate-hadrian: - <<: *only-default variables: FLAVOUR: "validate" script: @@ -250,7 +227,6 @@ validate-x86_64-linux-deb9-unreg-hadrian: TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" hadrian-ghc-in-ghci: - <<: *only-default stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" before_script: @@ -283,7 +259,6 @@ hadrian-ghc-in-ghci: ############################################################ .validate: - <<: *only-default variables: TEST_TYPE: test MAKE_ARGS: "-Werror" @@ -338,9 +313,8 @@ hadrian-ghc-in-ghci: validate-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/ + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/' nightly-x86_64-freebsd: <<: *nightly @@ -417,7 +391,6 @@ validate-x86_64-darwin: # Disabled because of OS X CI capacity .validate-x86_64-darwin-hadrian: - <<: *only-default stage: full-build tags: - x86_64-darwin @@ -780,7 +753,6 @@ validate-x86_64-linux-fedora27: ############################################################ .build-windows: - <<: *only-default # For the reasons given in #17777 this build isn't reliable. allow_failure: true before_script: @@ -954,7 +926,6 @@ nightly-i386-windows: # See Note [Cleanup after shell executor] cleanup-darwin: - <<: *only-default stage: cleanup tags: - x86_64-darwin @@ -976,7 +947,6 @@ cleanup-darwin: ############################################################ doc-tarball: - <<: *only-default stage: packaging tags: - x86_64-linux @@ -1016,10 +986,10 @@ source-tarball: tags: - x86_64-linux image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - when: always dependencies: [] - only: - - tags + rules: + - if: $CI_COMMIT_TAG + when: always artifacts: paths: - ghc-*.tar.xz @@ -1046,7 +1016,6 @@ source-tarball: # pipeline. .hackage: - <<: *only-default stage: testing image: ghcci/x86_64-linux-deb9:0.2 tags: @@ -1063,9 +1032,8 @@ hackage: hackage-label: extends: .hackage - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/ + rules: + if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' nightly-hackage: <<: *nightly @@ -1080,11 +1048,10 @@ perf-nofib: dependencies: - validate-x86_64-linux-deb9-dwarf image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - only: - refs: - - merge_requests - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: $CI_MERGE_REQUEST_ID + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' tags: - x86_64-linux script: @@ -1133,8 +1100,8 @@ pages: EOF - cp -f index.html public/doc - only: - - master + rules: + - if: '$CI_COMMIT_BRANCH == "master"' artifacts: paths: - public View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15edbb2f5ad60035715d61ee21c6a2e5c85ff04c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15edbb2f5ad60035715d61ee21c6a2e5c85ff04c You're receiving 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 15 17:51:59 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 13:51:59 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] gitlab-ci: Use rules syntax for conditional jobs Message-ID: <5e9749bf1d9dd_616776d1c74517195a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: 53b70e27 by Ben Gamari at 2020-04-15T13:51:47-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -26,19 +26,18 @@ stages: - testing # head.hackage correctness and compiler performance testing - deploy # push documentation -# N.B.Don't run on wip/ branches, instead on run on merge requests. -.only-default: &only-default - only: - - master - - /ghc-[0-9]+\.[0-9]+/ - - merge_requests - - tags - - web +workflow: + # N.B.Don't run on wip/ branches, instead on run on merge requests. + rules: + - if: $CI_MERGE_REQUEST_ID + - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' + - if: '$CI_PIPELINE_SOURCE == "web"' .nightly: &nightly - only: - variables: - - $NIGHTLY + rules: + - if: $NIGHTLY artifacts: when: always expire_in: 8 weeks @@ -50,9 +49,8 @@ stages: artifacts: when: always expire_in: 1 year - only: - variables: - - $RELEASE == "yes" + rules: + - if: '$RELEASE == "yes"' ############################################################ # Runner Tags @@ -86,13 +84,11 @@ ghc-linters: dependencies: [] tags: - lint - only: - refs: - - merge_requests + rules: + - if: $CI_MERGE_REQUEST_ID # Run mypy Python typechecker on linter scripts. lint-linters: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -103,7 +99,6 @@ lint-linters: # Check that .T files all parse by listing broken tests. lint-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" script: @@ -114,7 +109,6 @@ lint-testsuite: # Run mypy Python typechecker on testsuite driver typecheck-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -127,7 +121,6 @@ typecheck-testsuite: # accommodate, e.g., haddock changes not yet upstream) but not on `master` or # Marge jobs. .lint-submods: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -140,25 +133,14 @@ typecheck-testsuite: tags: - lint -lint-submods-marge: +lint-submods: extends: .lint-submods - only: - refs: - - merge_requests - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" - -lint-submods-mr: - extends: .lint-submods - # Allow failure since any necessary submodule patches may not be upstreamed - # yet. - allow_failure: true - only: - refs: - - merge_requests - except: - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" + # Allow failure on merge requests since any necessary submodule patches may + # not be upstreamed yet. + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' + allow_failure: false + - allow_failure: true lint-submods-branch: extends: .lint-submods @@ -166,13 +148,11 @@ lint-submods-branch: - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - git submodule foreach git remote update - submodchecker . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) - only: - refs: - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' .lint-changelogs: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" dependencies: [] @@ -185,15 +165,13 @@ lint-changelogs: extends: .lint-changelogs # Allow failure since this isn't a final release. allow_failure: true - only: - refs: - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' lint-release-changelogs: extends: .lint-changelogs - only: - refs: - - /ghc-[0-9]+\.[0-9]+\.[0-9]+-.*/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' ############################################################ @@ -201,7 +179,6 @@ lint-release-changelogs: ############################################################ .validate-hadrian: - <<: *only-default variables: FLAVOUR: "validate" script: @@ -250,7 +227,6 @@ validate-x86_64-linux-deb9-unreg-hadrian: TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" hadrian-ghc-in-ghci: - <<: *only-default stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" before_script: @@ -283,7 +259,6 @@ hadrian-ghc-in-ghci: ############################################################ .validate: - <<: *only-default variables: TEST_TYPE: test MAKE_ARGS: "-Werror" @@ -338,9 +313,8 @@ hadrian-ghc-in-ghci: validate-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/ + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/' nightly-x86_64-freebsd: <<: *nightly @@ -417,7 +391,6 @@ validate-x86_64-darwin: # Disabled because of OS X CI capacity .validate-x86_64-darwin-hadrian: - <<: *only-default stage: full-build tags: - x86_64-darwin @@ -780,7 +753,6 @@ validate-x86_64-linux-fedora27: ############################################################ .build-windows: - <<: *only-default # For the reasons given in #17777 this build isn't reliable. allow_failure: true before_script: @@ -954,7 +926,6 @@ nightly-i386-windows: # See Note [Cleanup after shell executor] cleanup-darwin: - <<: *only-default stage: cleanup tags: - x86_64-darwin @@ -976,7 +947,6 @@ cleanup-darwin: ############################################################ doc-tarball: - <<: *only-default stage: packaging tags: - x86_64-linux @@ -1016,10 +986,10 @@ source-tarball: tags: - x86_64-linux image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - when: always dependencies: [] - only: - - tags + rules: + - if: $CI_COMMIT_TAG + when: always artifacts: paths: - ghc-*.tar.xz @@ -1046,7 +1016,6 @@ source-tarball: # pipeline. .hackage: - <<: *only-default stage: testing image: ghcci/x86_64-linux-deb9:0.2 tags: @@ -1063,9 +1032,8 @@ hackage: hackage-label: extends: .hackage - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/ + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' nightly-hackage: <<: *nightly @@ -1080,11 +1048,10 @@ perf-nofib: dependencies: - validate-x86_64-linux-deb9-dwarf image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - only: - refs: - - merge_requests - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: $CI_MERGE_REQUEST_ID + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' tags: - x86_64-linux script: @@ -1133,8 +1100,8 @@ pages: EOF - cp -f index.html public/doc - only: - - master + rules: + - if: '$CI_COMMIT_BRANCH == "master"' artifacts: paths: - public View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53b70e27bd87b1efbc4f71f7fd06ab959369ff46 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53b70e27bd87b1efbc4f71f7fd06ab959369ff46 You're receiving 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 15 19:56:17 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 15 Apr 2020 15:56:17 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/tune_layout Message-ID: <5e9766e1f210f_61673f8198ee100c5174929@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/tune_layout at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/tune_layout You're receiving 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 15 20:20:41 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 16:20:41 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] 11 commits: testsuite: Move no_lint to the top level, tweak hie002 Message-ID: <5e976c9989ac9_616765c7a28517822d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 33bb8bc2 by Ben Gamari at 2020-04-15T16:20:33-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 3cf79472 by Ben Gamari at 2020-04-15T16:20:33-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - b0ac5181 by Ben Gamari at 2020-04-15T16:20:33-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/utils/Binary.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/extending_ghc.rst - docs/users_guide/exts/existential_quantification.rst - + docs/users_guide/exts/field_selectors_and_type_applications.rst - docs/users_guide/exts/gadt.rst - docs/users_guide/exts/rank_polymorphism.rst - docs/users_guide/exts/records.rst - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Packages.hs - libraries/base/Control/Category.hs - libraries/base/GHC/Desugar.hs - testsuite/driver/testlib.py - testsuite/tests/driver/T4437.hs - testsuite/tests/ghci/linking/all.T - testsuite/tests/hiefile/should_compile/all.T - + testsuite/tests/indexed-types/should_compile/T17923.hs - testsuite/tests/indexed-types/should_compile/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53b70e27bd87b1efbc4f71f7fd06ab959369ff46...b0ac51819638036b7ec23319bb15e224a2c76cf1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53b70e27bd87b1efbc4f71f7fd06ab959369ff46...b0ac51819638036b7ec23319bb15e224a2c76cf1 You're receiving 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 15 21:24:19 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 17:24:19 -0400 Subject: [Git][ghc/ghc][wip/with2] 105 commits: Refactoring: use Platform instead of DynFlags when possible Message-ID: <5e977b8332401_6167134ebbc4518015d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2 at Glasgow Haskell Compiler / GHC Commits: 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 1d2e1f0c by Ben Gamari at 2020-04-14T12:04:07-04:00 Introduce with# - - - - - eee8ac07 by Ben Gamari at 2020-04-14T12:47:08-04:00 Rename to keepAlive# - - - - - 235bf316 by Ben Gamari at 2020-04-15T15:02:44-04:00 Things - - - - - 24d0d597 by Ben Gamari at 2020-04-15T15:11:52-04:00 Use with# - - - - - 62fca4e1 by Ben Gamari at 2020-04-15T16:13:00-04:00 Fix it - - - - - 1938fe8e by Ben Gamari at 2020-04-15T17:23:52-04:00 It works - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/linters/check-cpp.py - CODEOWNERS - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c402471377ac14014a46c6029d31d4d8d3571d21...1938fe8e81da5bb822ceec920d91ef3e80d2272a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c402471377ac14014a46c6029d31d4d8d3571d21...1938fe8e81da5bb822ceec920d91ef3e80d2272a You're receiving 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 15 21:48:57 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 15 Apr 2020 17:48:57 -0400 Subject: [Git][ghc/ghc][master] Fix #18052 by using pprPrefixOcc in more places Message-ID: <5e978149c605f_616776d1c74519156@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - 9 changed files: - compiler/GHC/Core/Ppr.hs - compiler/GHC/Tc/Module.hs - + testsuite/tests/ghci/should_fail/T18052b.script - + testsuite/tests/ghci/should_fail/T18052b.stderr - testsuite/tests/ghci/should_fail/all.T - testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr - + testsuite/tests/printer/T18052a.hs - + testsuite/tests/printer/T18052a.stderr - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -123,11 +123,13 @@ ppr_binding ann (val_bdr, expr) , pp_bind ] where + pp_val_bdr = pprPrefixOcc val_bdr + pp_bind = case bndrIsJoin_maybe val_bdr of Nothing -> pp_normal_bind Just ar -> pp_join_bind ar - pp_normal_bind = hang (ppr val_bdr) 2 (equals <+> pprCoreExpr expr) + pp_normal_bind = hang pp_val_bdr 2 (equals <+> pprCoreExpr expr) -- For a join point of join arity n, we want to print j = \x1 ... xn -> e -- as "j x1 ... xn = e" to differentiate when a join point returns a @@ -135,7 +137,7 @@ ppr_binding ann (val_bdr, expr) -- an n-argument function). pp_join_bind join_arity | bndrs `lengthAtLeast` join_arity - = hang (ppr val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) + = hang (pp_val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) 2 (equals <+> pprCoreExpr rhs) | otherwise -- Yikes! A join-binding with too few lambda -- Lint will complain, but we don't want to crash @@ -164,8 +166,10 @@ ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc -- an atomic value (e.g. function args) ppr_expr add_par (Var name) - | isJoinId name = add_par ((text "jump") <+> ppr name) - | otherwise = ppr name + | isJoinId name = add_par ((text "jump") <+> pp_name) + | otherwise = pp_name + where + pp_name = pprPrefixOcc name ppr_expr add_par (Type ty) = add_par (text "TYPE:" <+> ppr ty) -- Weird ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> ppr co) ppr_expr add_par (Lit lit) = pprLiteral add_par lit @@ -429,7 +433,7 @@ pprKindedTyVarBndr tyvar -- pprIdBndr does *not* print the type -- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness pprIdBndr :: Id -> SDoc -pprIdBndr id = ppr id <+> pprIdBndrInfo (idInfo id) +pprIdBndr id = pprPrefixOcc id <+> pprIdBndrInfo (idInfo id) pprIdBndrInfo :: IdInfo -> SDoc pprIdBndrInfo info ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2122,7 +2122,7 @@ tcRnStmt hsc_env rdr_stmt } where bad_unboxed id = addErr (sep [text "GHCi can't bind a variable of unlifted type:", - nest 2 (ppr id <+> dcolon <+> ppr (idType id))]) + nest 2 (pprPrefixOcc id <+> dcolon <+> ppr (idType id))]) {- -------------------------------------------------------------------------- @@ -2903,7 +2903,7 @@ ppr_types debug type_env -- etc are suppressed (unless -dppr-debug), -- because they appear elsewhere - ppr_sig id = hang (ppr id <+> dcolon) 2 (ppr (tidyTopType (idType id))) + ppr_sig id = hang (pprPrefixOcc id <+> dcolon) 2 (ppr (tidyTopType (idType id))) ppr_tycons :: Bool -> [FamInst] -> TypeEnv -> SDoc ppr_tycons debug fam_insts type_env @@ -2921,7 +2921,7 @@ ppr_tycons debug fam_insts type_env | otherwise = isExternalName (tyConName tycon) && not (tycon `elem` fi_tycons) ppr_tc tc - = vcat [ hang (ppr (tyConFlavour tc) <+> ppr tc + = vcat [ hang (ppr (tyConFlavour tc) <+> pprPrefixOcc (tyConName tc) <> braces (ppr (tyConArity tc)) <+> dcolon) 2 (ppr (tidyTopType (tyConKind tc))) , nest 2 $ @@ -2955,7 +2955,7 @@ ppr_patsyns type_env = ppr_things "PATTERN SYNONYMS" ppr_ps (typeEnvPatSyns type_env) where - ppr_ps ps = ppr ps <+> dcolon <+> pprPatSynType ps + ppr_ps ps = pprPrefixOcc ps <+> dcolon <+> pprPatSynType ps ppr_insts :: [ClsInst] -> SDoc ppr_insts ispecs ===================================== testsuite/tests/ghci/should_fail/T18052b.script ===================================== @@ -0,0 +1,2 @@ +:set -XMagicHash +let (%%%) = 1# ===================================== testsuite/tests/ghci/should_fail/T18052b.stderr ===================================== @@ -0,0 +1,3 @@ + +:1:1: error: + GHCi can't bind a variable of unlifted type: (%%%) :: GHC.Prim.Int# ===================================== testsuite/tests/ghci/should_fail/all.T ===================================== @@ -3,3 +3,4 @@ test('T10549a', [], ghci_script, ['T10549a.script']) test('T15055', normalise_version('ghc'), ghci_script, ['T15055.script']) test('T16013', [], ghci_script, ['T16013.script']) test('T16287', [], ghci_script, ['T16287.script']) +test('T18052b', [], ghci_script, ['T18052b.script']) ===================================== testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr ===================================== @@ -1,28 +1,28 @@ TYPE SIGNATURES - !! :: forall {a}. [a] -> Int -> a - $ :: forall {a} {b}. (a -> b) -> a -> b - $! :: forall {a} {b}. (a -> b) -> a -> b - && :: Bool -> Bool -> Bool - * :: forall {a}. Num a => a -> a -> a - ** :: forall {a}. Floating a => a -> a -> a - + :: forall {a}. Num a => a -> a -> a - ++ :: forall {a}. [a] -> [a] -> [a] - - :: forall {a}. Num a => a -> a -> a - . :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c - / :: forall {a}. Fractional a => a -> a -> a - /= :: forall {a}. Eq a => a -> a -> Bool - < :: forall {a}. Ord a => a -> a -> Bool - <= :: forall {a}. Ord a => a -> a -> Bool - =<< :: + (!!) :: forall {a}. [a] -> Int -> a + ($) :: forall {a} {b}. (a -> b) -> a -> b + ($!) :: forall {a} {b}. (a -> b) -> a -> b + (&&) :: Bool -> Bool -> Bool + (*) :: forall {a}. Num a => a -> a -> a + (**) :: forall {a}. Floating a => a -> a -> a + (+) :: forall {a}. Num a => a -> a -> a + (++) :: forall {a}. [a] -> [a] -> [a] + (-) :: forall {a}. Num a => a -> a -> a + (.) :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c + (/) :: forall {a}. Fractional a => a -> a -> a + (/=) :: forall {a}. Eq a => a -> a -> Bool + (<) :: forall {a}. Ord a => a -> a -> Bool + (<=) :: forall {a}. Ord a => a -> a -> Bool + (=<<) :: forall {m :: * -> *} {a} {b}. Monad m => (a -> m b) -> m a -> m b - == :: forall {a}. Eq a => a -> a -> Bool - > :: forall {a}. Ord a => a -> a -> Bool - >= :: forall {a}. Ord a => a -> a -> Bool - >> :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b - >>= :: + (==) :: forall {a}. Eq a => a -> a -> Bool + (>) :: forall {a}. Ord a => a -> a -> Bool + (>=) :: forall {a}. Ord a => a -> a -> Bool + (>>) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b + (>>=) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> (a -> m b) -> m b - ^ :: forall {b} {a}. (Integral b, Num a) => a -> b -> a - ^^ :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a + (^) :: forall {b} {a}. (Integral b, Num a) => a -> b -> a + (^^) :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a abs :: forall {a}. Num a => a -> a acos :: forall {a}. Floating a => a -> a acosh :: forall {a}. Floating a => a -> a @@ -234,7 +234,7 @@ TYPE SIGNATURES zipWith3 :: forall {a} {b} {c} {d}. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] - || :: Bool -> Bool -> Bool + (||) :: Bool -> Bool -> Bool Dependent modules: [] -Dependent packages: [base-4.13.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeOperators #-} +module T18052a where + +(+++) = (++) +pattern x :||: y = (x,y) +type (^^^) = Either +data (&&&) ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -0,0 +1,42 @@ +TYPE SIGNATURES + (+++) :: forall {a}. [a] -> [a] -> [a] +TYPE CONSTRUCTORS + data type (&&&){0} :: * + type synonym (^^^){0} :: * -> * -> * +PATTERN SYNONYMS + (:||:) :: forall {a} {b}. a -> b -> (a, b) +Dependent modules: [] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 18, types: 53, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) +[GblId, Arity=2, Unf=OtherCon []] +T18052a.$b:||: = GHC.Tuple.(,) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +(+++) :: forall {a}. [a] -> [a] -> [a] +[GblId] +(+++) = (++) + +-- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +T18052a.$m:||: + :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. + (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r +[GblId, Arity=3, Unf=OtherCon []] +T18052a.$m:||: + = \ (@(rep :: GHC.Types.RuntimeRep)) + (@(r :: TYPE rep)) + (@a) + (@b) + (scrut :: (a, b)) + (cont :: a -> b -> r) + _ [Occ=Dead] -> + case scrut of { (x, y) -> cont x y } + + + ===================================== testsuite/tests/printer/all.T ===================================== @@ -57,3 +57,5 @@ test('T14306', ignore_stderr, makefile_test, ['T14306']) test('T14343', normal, compile_fail, ['']) test('T14343b', normal, compile_fail, ['']) test('T15761', normal, compile_fail, ['']) +test('T18052a', normal, compile, + ['-ddump-simpl -ddump-types -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22cc8e513fcfa89a4391f075534d903596a05895 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22cc8e513fcfa89a4391f075534d903596a05895 You're receiving 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 15 21:49:33 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 15 Apr 2020 17:49:33 -0400 Subject: [Git][ghc/ghc][master] rts: ProfHeap: Fix wrong time in last heap profile sample Message-ID: <5e97816dcda0f_616713503ee051946f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 1 changed file: - rts/ProfHeap.c Changes: ===================================== rts/ProfHeap.c ===================================== @@ -552,8 +552,6 @@ initHeapProfiling(void) void endHeapProfiling(void) { - StgDouble seconds; - if (! RtsFlags.ProfFlags.doHeapProfile) { return; } @@ -596,7 +594,10 @@ endHeapProfiling(void) stgFree(censuses); - seconds = mut_user_time(); + RTSStats stats; + getRTSStats(&stats); + Time mut_time = stats.mutator_cpu_ns; + StgDouble seconds = TimeToSecondsDbl(mut_time); printSample(true, seconds); printSample(false, seconds); fclose(hp_file); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec77b2f16a78b13f54794c954953d8878dea9db2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec77b2f16a78b13f54794c954953d8878dea9db2 You're receiving 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 15 22:21:41 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 18:21:41 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 88 commits: Fix ApplicativeDo regression #17835 Message-ID: <5e9788f51d391_6167136dfb9c52016cd@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 1d2e1f0c by Ben Gamari at 2020-04-14T12:04:07-04:00 Introduce with# - - - - - eee8ac07 by Ben Gamari at 2020-04-14T12:47:08-04:00 Rename to keepAlive# - - - - - 235bf316 by Ben Gamari at 2020-04-15T15:02:44-04:00 Things - - - - - 24d0d597 by Ben Gamari at 2020-04-15T15:11:52-04:00 Use with# - - - - - 62fca4e1 by Ben Gamari at 2020-04-15T16:13:00-04:00 Fix it - - - - - 1938fe8e by Ben Gamari at 2020-04-15T17:23:52-04:00 It works - - - - - 30 changed files: - .gitlab-ci.yml - CODEOWNERS - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Cmm/Sink.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c68e753b0eff399d4b6fbece5227d1700fd90903...1938fe8e81da5bb822ceec920d91ef3e80d2272a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c68e753b0eff399d4b6fbece5227d1700fd90903...1938fe8e81da5bb822ceec920d91ef3e80d2272a You're receiving 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 15 22:42:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 18:42:23 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Adapt to Simon's simplifier approach Message-ID: <5e978dcf7903_61673f8198ee100c52057cb@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 1b156d64 by Ben Gamari at 2020-04-15T18:42:02-04:00 Adapt to Simon's simplifier approach - - - - - 2 changed files: - compiler/GHC/Core/Op/Simplify.hs - libraries/base/GHC/ForeignPtr.hs Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -1791,40 +1791,6 @@ completeCall env var cont ; dump_inline expr cont ; simplExprF (zapSubstEnv env) expr cont } - -- Push strict contexts into with# continuation - -- - -- That is, - -- - -- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) - -- ~> - -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 - | var `hasKey` keepAliveIdKey - , ApplyToTy arg_rep hole1 cont1 <- -- cont - pprTrace "completeCall(keepAlive#)" (ppr var $$ ppr cont) cont - , ApplyToTy arg_ty hole2 cont2 <- cont1 - , ApplyToTy _res_rep _ cont3 <- cont2 - , ApplyToTy _res_ty _ cont4 <- cont3 - , ApplyToVal dup5 x env5 cont5 <- cont4 - , ApplyToVal dup6 f env6 cont6 <- cont5 - , ApplyToVal dup7 s0 env7 cont7 <- cont6 - , not $ contIsStop cont7 - , Lam f_arg f_rhs <- etaExpand 1 f - = do { let out_ty = contResultType cont - out_rep = getRuntimeRep out_ty - ; (floats1, f') <- rebuild env6 f_rhs cont7 - ; let cont' = - ApplyToTy arg_rep hole1 - $ ApplyToTy arg_ty hole2 - $ ApplyToTy out_rep undefined - $ ApplyToTy out_ty undefined - $ ApplyToVal dup5 x env5 - $ ApplyToVal dup6 (Lam f_arg f') env6 - $ ApplyToVal dup7 s0 env7 - $ mkBoringStop out_ty - ; (floats2, result) <- completeCall env var cont' - ; pprTrace "rebuilt" (ppr result) $ return (floats1 `addFloats` floats2, result) - } - | otherwise -- Don't inline; instead rebuild the call = do { rule_base <- getSimplRules @@ -1907,6 +1873,38 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args _ -> True +---------- Simplify continuation-passing primops -------------- +-- Push strict contexts into keepAlive# continuation +-- +-- That is, +-- +-- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) +-- ~> +-- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` keepAliveIdKey + , [ ValArg s0 + , ValArg (Lam f_arg f_body) + , ValArg x + , TyArg _res_ty + , TyArg _res_rep + , TyArg _arg_ty + , TyArg _arg_rep + ] <- f + = { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg + ; body' <- simplExprC env' body cont + ; let f' = Lam f_arg body' + ty' = contResultType cont + rep' = getRuntimeRep out_ty + call' = mkApps (Var fun) + [ mkTyArg rep', mkTyArg ty' + , mkTyArg arg_rep, mkTyArg arg_ty + , x + , f' + , s0 + ] + ; return (emptyFloats env, call') } + ---------- Simplify applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -412,7 +412,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r (\s' -> action# s') s + IO action# -> keepAlive# r action# s touchForeignPtr :: ForeignPtr a -> IO () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b156d644b226c25916dcf65b9145b1ec3d260a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b156d644b226c25916dcf65b9145b1ec3d260a0 You're receiving 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 15 22:45:55 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 18:45:55 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] 22 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5e978ea3a8000_6167134ebbc4520666@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 562aff66 by Ben Gamari at 2020-04-15T18:44:54-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - a74b41df by Ben Gamari at 2020-04-15T18:44:54-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - 2a60c523 by Ben Gamari at 2020-04-15T18:44:54-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 51ff03dd by Ben Gamari at 2020-04-15T18:45:36-04:00 Bump hsc2hs submodule - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/ghc.cabal.in - ghc.mk - hadrian/src/Builder.hs - hadrian/src/Rules/SourceDist.hs - hadrian/src/Settings/Builders/Ghc.hs - includes/rts/storage/ClosureMacros.h - includes/rts/storage/GC.h - libraries/base/Data/Foldable.hs - libraries/base/GHC/IO/Handle/Lock/LinuxOFD.hsc - libraries/exceptions - libraries/ghci/ghci.cabal.in - libraries/template-haskell/template-haskell.cabal.in - libraries/text - rts/Apply.cmm The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b0ac51819638036b7ec23319bb15e224a2c76cf1...51ff03dd3d7ce396c885db06a3ffc61543d3a2b7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b0ac51819638036b7ec23319bb15e224a2c76cf1...51ff03dd3d7ce396c885db06a3ffc61543d3a2b7 You're receiving 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 15 22:49:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 18:49:28 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Adapt to Simon's simplifier approach Message-ID: <5e978f78865be_61677c82e0c52091c8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 15e3a43d by Ben Gamari at 2020-04-15T18:49:18-04:00 Adapt to Simon's simplifier approach - - - - - 2 changed files: - compiler/GHC/Core/Op/Simplify.hs - libraries/base/GHC/ForeignPtr.hs Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -1791,40 +1791,6 @@ completeCall env var cont ; dump_inline expr cont ; simplExprF (zapSubstEnv env) expr cont } - -- Push strict contexts into with# continuation - -- - -- That is, - -- - -- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) - -- ~> - -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 - | var `hasKey` keepAliveIdKey - , ApplyToTy arg_rep hole1 cont1 <- -- cont - pprTrace "completeCall(keepAlive#)" (ppr var $$ ppr cont) cont - , ApplyToTy arg_ty hole2 cont2 <- cont1 - , ApplyToTy _res_rep _ cont3 <- cont2 - , ApplyToTy _res_ty _ cont4 <- cont3 - , ApplyToVal dup5 x env5 cont5 <- cont4 - , ApplyToVal dup6 f env6 cont6 <- cont5 - , ApplyToVal dup7 s0 env7 cont7 <- cont6 - , not $ contIsStop cont7 - , Lam f_arg f_rhs <- etaExpand 1 f - = do { let out_ty = contResultType cont - out_rep = getRuntimeRep out_ty - ; (floats1, f') <- rebuild env6 f_rhs cont7 - ; let cont' = - ApplyToTy arg_rep hole1 - $ ApplyToTy arg_ty hole2 - $ ApplyToTy out_rep undefined - $ ApplyToTy out_ty undefined - $ ApplyToVal dup5 x env5 - $ ApplyToVal dup6 (Lam f_arg f') env6 - $ ApplyToVal dup7 s0 env7 - $ mkBoringStop out_ty - ; (floats2, result) <- completeCall env var cont' - ; pprTrace "rebuilt" (ppr result) $ return (floats1 `addFloats` floats2, result) - } - | otherwise -- Don't inline; instead rebuild the call = do { rule_base <- getSimplRules @@ -1907,6 +1873,38 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args _ -> True +---------- Simplify continuation-passing primops -------------- +-- Push strict contexts into keepAlive# continuation +-- +-- That is, +-- +-- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) +-- ~> +-- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` keepAliveIdKey + , [ ValArg s0 + , ValArg (Lam f_arg f_body) + , ValArg x + , TyArg _res_ty + , TyArg _res_rep + , TyArg _arg_ty + , TyArg _arg_rep + ] <- f + = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg + ; body' <- simplExprC env' body cont + ; let f' = Lam f_arg body' + ty' = contResultType cont + rep' = getRuntimeRep out_ty + call' = mkApps (Var fun) + [ mkTyArg rep', mkTyArg ty' + , mkTyArg arg_rep, mkTyArg arg_ty + , x + , f' + , s0 + ] + ; return (emptyFloats env, call') } + ---------- Simplify applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -412,7 +412,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r (\s' -> action# s') s + IO action# -> keepAlive# r action# s touchForeignPtr :: ForeignPtr a -> IO () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15e3a43dafebbc3bb2c655c4cf7aaa42f15cc95e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15e3a43dafebbc3bb2c655c4cf7aaa42f15cc95e You're receiving 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 15 23:09:34 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 19:09:34 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Adapt to Simon's simplifier approach Message-ID: <5e97942e4e154_61677c82e0c521009b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: c2557de7 by Ben Gamari at 2020-04-15T19:09:27-04:00 Adapt to Simon's simplifier approach - - - - - 2 changed files: - compiler/GHC/Core/Op/Simplify.hs - libraries/base/GHC/ForeignPtr.hs Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -1791,40 +1791,6 @@ completeCall env var cont ; dump_inline expr cont ; simplExprF (zapSubstEnv env) expr cont } - -- Push strict contexts into with# continuation - -- - -- That is, - -- - -- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) - -- ~> - -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 - | var `hasKey` keepAliveIdKey - , ApplyToTy arg_rep hole1 cont1 <- -- cont - pprTrace "completeCall(keepAlive#)" (ppr var $$ ppr cont) cont - , ApplyToTy arg_ty hole2 cont2 <- cont1 - , ApplyToTy _res_rep _ cont3 <- cont2 - , ApplyToTy _res_ty _ cont4 <- cont3 - , ApplyToVal dup5 x env5 cont5 <- cont4 - , ApplyToVal dup6 f env6 cont6 <- cont5 - , ApplyToVal dup7 s0 env7 cont7 <- cont6 - , not $ contIsStop cont7 - , Lam f_arg f_rhs <- etaExpand 1 f - = do { let out_ty = contResultType cont - out_rep = getRuntimeRep out_ty - ; (floats1, f') <- rebuild env6 f_rhs cont7 - ; let cont' = - ApplyToTy arg_rep hole1 - $ ApplyToTy arg_ty hole2 - $ ApplyToTy out_rep undefined - $ ApplyToTy out_ty undefined - $ ApplyToVal dup5 x env5 - $ ApplyToVal dup6 (Lam f_arg f') env6 - $ ApplyToVal dup7 s0 env7 - $ mkBoringStop out_ty - ; (floats2, result) <- completeCall env var cont' - ; pprTrace "rebuilt" (ppr result) $ return (floats1 `addFloats` floats2, result) - } - | otherwise -- Don't inline; instead rebuild the call = do { rule_base <- getSimplRules @@ -1907,6 +1873,38 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args _ -> True +---------- Simplify continuation-passing primops -------------- +-- Push strict contexts into keepAlive# continuation +-- +-- That is, +-- +-- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) +-- ~> +-- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` keepAliveIdKey + , [ ValArg s0 + , ValArg (Lam f_arg f_body) + , ValArg x + , TyArg {} + , TyArg {} + , TyArg {as_arg_ty=arg_ty} + , TyArg {as_arg_ty=arg_rep} + ] <- f + = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg + ; body' <- simplExprC env' body cont + ; let f' = Lam f_arg body' + ty' = contResultType cont + rep' = getRuntimeRep out_ty + call' = mkApps (Var fun) + [ mkTyArg rep', mkTyArg ty' + , mkTyArg arg_rep, mkTyArg arg_ty + , x + , f' + , s0 + ] + ; return (emptyFloats env, call') } + ---------- Simplify applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -412,7 +412,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r (\s' -> action# s') s + IO action# -> keepAlive# r action# s touchForeignPtr :: ForeignPtr a -> IO () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2557de74debcbe084a0308161d7ff55bde132b7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2557de74debcbe084a0308161d7ff55bde132b7 You're receiving 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 15 23:12:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 19:12:22 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Adapt to Simon's simplifier approach Message-ID: <5e9794d642c40_61673f8199536d945210911@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 45bc8402 by Ben Gamari at 2020-04-15T19:12:14-04:00 Adapt to Simon's simplifier approach - - - - - 2 changed files: - compiler/GHC/Core/Op/Simplify.hs - libraries/base/GHC/ForeignPtr.hs Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -1791,40 +1791,6 @@ completeCall env var cont ; dump_inline expr cont ; simplExprF (zapSubstEnv env) expr cont } - -- Push strict contexts into with# continuation - -- - -- That is, - -- - -- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) - -- ~> - -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 - | var `hasKey` keepAliveIdKey - , ApplyToTy arg_rep hole1 cont1 <- -- cont - pprTrace "completeCall(keepAlive#)" (ppr var $$ ppr cont) cont - , ApplyToTy arg_ty hole2 cont2 <- cont1 - , ApplyToTy _res_rep _ cont3 <- cont2 - , ApplyToTy _res_ty _ cont4 <- cont3 - , ApplyToVal dup5 x env5 cont5 <- cont4 - , ApplyToVal dup6 f env6 cont6 <- cont5 - , ApplyToVal dup7 s0 env7 cont7 <- cont6 - , not $ contIsStop cont7 - , Lam f_arg f_rhs <- etaExpand 1 f - = do { let out_ty = contResultType cont - out_rep = getRuntimeRep out_ty - ; (floats1, f') <- rebuild env6 f_rhs cont7 - ; let cont' = - ApplyToTy arg_rep hole1 - $ ApplyToTy arg_ty hole2 - $ ApplyToTy out_rep undefined - $ ApplyToTy out_ty undefined - $ ApplyToVal dup5 x env5 - $ ApplyToVal dup6 (Lam f_arg f') env6 - $ ApplyToVal dup7 s0 env7 - $ mkBoringStop out_ty - ; (floats2, result) <- completeCall env var cont' - ; pprTrace "rebuilt" (ppr result) $ return (floats1 `addFloats` floats2, result) - } - | otherwise -- Don't inline; instead rebuild the call = do { rule_base <- getSimplRules @@ -1907,6 +1873,37 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args _ -> True +---------- Simplify continuation-passing primops -------------- +-- Push strict contexts into keepAlive# continuation +-- +-- That is, +-- +-- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) +-- ~> +-- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` keepAliveIdKey + , [ ValArg s0 + , ValArg (Lam f_arg f_body) + , ValArg x + , TyArg {} + , TyArg {} + , TyArg {as_arg_ty=arg_ty} + , TyArg {as_arg_ty=arg_rep} + ] <- rev_args + = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg + ; f_body' <- simplExprC env' f_body cont + ; let f' = Lam f_arg f_body' + ty' = contResultType cont + call' = mkApps (Var fun) + [ mkTyArg (getRuntimeRep ty'), mkTyArg ty' + , mkTyArg arg_rep, mkTyArg arg_ty + , x + , f' + , s0 + ] + ; return (emptyFloats env, call') } + ---------- Simplify applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -412,7 +412,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r (\s' -> action# s') s + IO action# -> keepAlive# r action# s touchForeignPtr :: ForeignPtr a -> IO () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/45bc840219bbe5284d93e52aa30d6c0aa1abd11b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/45bc840219bbe5284d93e52aa30d6c0aa1abd11b You're receiving 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 15 23:50:02 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 19:50:02 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Adapt to Simon's simplifier approach Message-ID: <5e979daad7471_61673f81ef22dee4521287b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 2ccce995 by Ben Gamari at 2020-04-15T19:49:54-04:00 Adapt to Simon's simplifier approach - - - - - 3 changed files: - compiler/GHC/Core/Op/Simplify.hs - compiler/prelude/PrelNames.hs - libraries/base/GHC/ForeignPtr.hs Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -15,7 +15,6 @@ import GhcPrelude import GHC.Platform import GHC.Driver.Session -import GHC.Core.Arity ( etaExpand ) import GHC.Core.Op.Simplify.Monad import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst ) import GHC.Core.Op.Simplify.Env @@ -1791,40 +1790,6 @@ completeCall env var cont ; dump_inline expr cont ; simplExprF (zapSubstEnv env) expr cont } - -- Push strict contexts into with# continuation - -- - -- That is, - -- - -- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) - -- ~> - -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 - | var `hasKey` keepAliveIdKey - , ApplyToTy arg_rep hole1 cont1 <- -- cont - pprTrace "completeCall(keepAlive#)" (ppr var $$ ppr cont) cont - , ApplyToTy arg_ty hole2 cont2 <- cont1 - , ApplyToTy _res_rep _ cont3 <- cont2 - , ApplyToTy _res_ty _ cont4 <- cont3 - , ApplyToVal dup5 x env5 cont5 <- cont4 - , ApplyToVal dup6 f env6 cont6 <- cont5 - , ApplyToVal dup7 s0 env7 cont7 <- cont6 - , not $ contIsStop cont7 - , Lam f_arg f_rhs <- etaExpand 1 f - = do { let out_ty = contResultType cont - out_rep = getRuntimeRep out_ty - ; (floats1, f') <- rebuild env6 f_rhs cont7 - ; let cont' = - ApplyToTy arg_rep hole1 - $ ApplyToTy arg_ty hole2 - $ ApplyToTy out_rep undefined - $ ApplyToTy out_ty undefined - $ ApplyToVal dup5 x env5 - $ ApplyToVal dup6 (Lam f_arg f') env6 - $ ApplyToVal dup7 s0 env7 - $ mkBoringStop out_ty - ; (floats2, result) <- completeCall env var cont' - ; pprTrace "rebuilt" (ppr result) $ return (floats1 `addFloats` floats2, result) - } - | otherwise -- Don't inline; instead rebuild the call = do { rule_base <- getSimplRules @@ -1907,6 +1872,37 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args _ -> True +---------- Simplify continuation-passing primops -------------- +-- Push strict contexts into keepAlive# continuation +-- +-- That is, +-- +-- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) +-- ~> +-- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` keepAliveIdKey + , [ ValArg s0 + , ValArg (Lam f_arg f_body) + , ValArg x + , TyArg {} + , TyArg {} + , TyArg {as_arg_ty=arg_ty} + , TyArg {as_arg_ty=arg_rep} + ] <- rev_args + = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg + ; f_body' <- simplExprC env' f_body cont + ; let f' = Lam f_arg f_body' + ty' = contResultType cont + call' = mkApps (Var fun) + [ mkTyArg (getRuntimeRep ty'), mkTyArg ty' + , mkTyArg arg_rep, mkTyArg arg_ty + , x + , f' + , s0 + ] + ; return (emptyFloats env, call') } + ---------- Simplify applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -246,7 +246,6 @@ basicKnownKeyNames ioTyConName, ioDataConName, runMainIOName, runRWName, - keepAliveIdName, -- Type representation types trModuleTyConName, trModuleDataConName, @@ -912,10 +911,9 @@ and it's convenient to write them all down in one place. wildCardName :: Name wildCardName = mkSystemVarName wildCardKey (fsLit "wild") -runMainIOName, runRWName, keepAliveIdName :: Name +runMainIOName, runRWName :: Name runMainIOName = varQual gHC_TOP_HANDLER (fsLit "runMainIO") runMainKey runRWName = varQual gHC_MAGIC (fsLit "runRW#") runRWKey -keepAliveIdName = varQual gHC_MAGIC (fsLit "keepAlive#") keepAliveIdKey orderingTyConName, ordLTDataConName, ordEQDataConName, ordGTDataConName :: Name orderingTyConName = tcQual gHC_TYPES (fsLit "Ordering") orderingTyConKey ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -412,7 +412,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r (\s' -> action# s') s + IO action# -> keepAlive# r action# s touchForeignPtr :: ForeignPtr a -> IO () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ccce995c91f8c037f906d66df5865b01a687f7b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ccce995c91f8c037f906d66df5865b01a687f7b You're receiving 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 16 00:59:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 20:59:33 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 3 commits: Add tests Message-ID: <5e97adf59c8fb_6167e4e49b45215383@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 17323cb1 by Ben Gamari at 2020-04-15T20:27:17-04:00 Add tests - - - - - 44651702 by Ben Gamari at 2020-04-15T20:27:26-04:00 Fix return type - - - - - 7b01122e by Ben Gamari at 2020-04-15T20:59:24-04:00 Fix it - - - - - 6 changed files: - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/CoreToStg/Prep.hs - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_compile/keepAliveSimplificationA.hs - + testsuite/tests/simplCore/should_run/T18061.hs - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -1885,18 +1885,22 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont , [ ValArg s0 , ValArg (Lam f_arg f_body) , ValArg x - , TyArg {} - , TyArg {} + , TyArg {} -- res_ty + , TyArg {} -- res_rep , TyArg {as_arg_ty=arg_ty} , TyArg {as_arg_ty=arg_rep} ] <- rev_args = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg ; f_body' <- simplExprC env' f_body cont ; let f' = Lam f_arg f_body' - ty' = contResultType cont - call' = mkApps (Var fun) - [ mkTyArg (getRuntimeRep ty'), mkTyArg ty' - , mkTyArg arg_rep, mkTyArg arg_ty + -- Extract type of second component of (# State# RealWorld, a #) + ty' = case splitTyConApp_maybe (contResultType cont) of + Just (tc, [_, _, _, ty]) -> ty + Nothing -> panic "rebuildCall: Malformed (#,#) type" + + ; let call' = mkApps (Var fun) + [ mkTyArg arg_rep, mkTyArg arg_ty + , mkTyArg (getRuntimeRep ty'), mkTyArg ty' , x , f' , s0 ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -857,13 +857,15 @@ cpeApp top_env expr _ -> cpe_app env arg [CpeApp (Var realWorldPrimId)] 1 -- See Note [CorePrep handling of keepAlive#] - cpe_app env (Var f) [CpeApp (Type _arg_rep), CpeApp (Type arg_ty), + cpe_app env (Var f) [CpeApp (Type arg_rep), CpeApp (Type arg_ty), CpeApp (Type result_rep), CpeApp (Type result_ty), CpeApp x, CpeApp k, CpeApp s0] 3 | f `hasKey` keepAliveIdKey = do { let voidRepTy = primRepToRuntimeRep VoidRep - ; b0 <- newVar $ mkTyConApp (tupleTyCon Unboxed 2) - [voidRepTy, result_rep, realWorldStatePrimTy, result_ty] + -- out_ty ~ (# State# RealWorld, a #) + out_ty = mkTyConApp (tupleTyCon Unboxed 2) + [voidRepTy, result_rep, realWorldStatePrimTy, result_ty] + ; b0 <- newVar out_ty ; y <- newVar result_ty ; s1 <- newVar realWorldStatePrimTy ; s2 <- newVar realWorldStatePrimTy @@ -875,9 +877,11 @@ cpeApp top_env expr stateResultAlt stateVar resultVar rhs = (DataAlt (tupleDataCon Unboxed 2), [stateVar, resultVar], rhs) - expr = Case (App k s0) b0 (varType b0) [stateResultAlt s1 y rhs1] - rhs1 = Case (mkApps (Var touchId) [Type arg_ty, x, Var s1]) s1 (varType s1) [(DEFAULT, [], rhs2)] - rhs2 = mkApps (Var $ dataConWrapId $ tupleDataCon Unboxed 2) [Var s2, Var y] + expr = Case (App k s0) b0 out_ty [stateResultAlt s1 y rhs1] + rhs1 = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, x, Var s1] + in Case scrut s2 out_ty [(DEFAULT, [], rhs2)] + rhs2 = mkApps (Var $ dataConWrapId $ tupleDataCon Unboxed 2) + [mkTyArg voidRepTy, mkTyArg result_rep, mkTyArg realWorldStatePrimTy, mkTyArg result_ty, Var s2, Var y] ; cpeBody env expr } cpe_app _env (Var f) args _ ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -327,3 +327,4 @@ test('T17966', # NB: T17810: -fspecialise-aggressively test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) +test('keepAliveSimplificationA', grep_errmsg(r'43#'), compile, ['-O -ddump-simpl']) ===================================== testsuite/tests/simplCore/should_compile/keepAliveSimplificationA.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE MagicHash #-} + +module Hi (g) where + +import GHC.Prim +import GHC.IO +import GHC.Int + +keepAlive :: a -> IO r -> IO r +keepAlive x f = IO $ \s -> keepAlive# x (unIO f) s +{-# INLINE keepAlive #-} + +f :: a -> IO Int +f x = keepAlive x $ return 41 + +-- The 'succ' should be folded into the continuation given to +-- keepAlive; constant folding will then turn the 41# into a 42#, which is what +-- we check for in this test. +g :: a -> IO Int +g x = succ <$> f x ===================================== testsuite/tests/simplCore/should_run/T18061.hs ===================================== @@ -0,0 +1,19 @@ +module T18061 where + +import Control.Concurrent +import Control.Monad +import Data.Word +import Foreign.Storable +import Foreign.ForeignPtr +import Numeric + +main :: IO () +main = do + replicateM_ 49 $ threadDelay 1 + fptr <- mallocForeignPtrBytes 4 + withForeignPtr fptr $ \p -> + forever $ do + poke p (0xDEADBEEF :: Word32) + threadDelay 10 + x <- peek p + unless (x == 0xDEADBEEF) $ putStrLn (showHex x "") ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -93,3 +93,4 @@ test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) test('T17151', [], multimod_compile_and_run, ['T17151', '']) +test('T18061', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2ccce995c91f8c037f906d66df5865b01a687f7b...7b01122e0159f2abeccef0376745e46355501555 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2ccce995c91f8c037f906d66df5865b01a687f7b...7b01122e0159f2abeccef0376745e46355501555 You're receiving 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 16 01:15:24 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 21:15:24 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 2 commits: Fix it Message-ID: <5e97b1ac8d230_616776d1c7452176c0@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: fd23f36f by Ben Gamari at 2020-04-15T21:15:07-04:00 Fix it - - - - - b4cb0d76 by Ben Gamari at 2020-04-15T21:15:10-04:00 Add debug output to getCallMethod - - - - - 3 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/StgToCmm/Closure.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -857,13 +857,15 @@ cpeApp top_env expr _ -> cpe_app env arg [CpeApp (Var realWorldPrimId)] 1 -- See Note [CorePrep handling of keepAlive#] - cpe_app env (Var f) [CpeApp (Type _arg_rep), CpeApp (Type arg_ty), + cpe_app env (Var f) [CpeApp (Type arg_rep), CpeApp (Type arg_ty), CpeApp (Type result_rep), CpeApp (Type result_ty), CpeApp x, CpeApp k, CpeApp s0] 3 | f `hasKey` keepAliveIdKey = do { let voidRepTy = primRepToRuntimeRep VoidRep - ; b0 <- newVar $ mkTyConApp (tupleTyCon Unboxed 2) - [voidRepTy, result_rep, realWorldStatePrimTy, result_ty] + -- out_ty ~ (# State# RealWorld, a #) + out_ty = mkTyConApp (tupleTyCon Unboxed 2) + [voidRepTy, result_rep, realWorldStatePrimTy, result_ty] + ; b0 <- newVar out_ty ; y <- newVar result_ty ; s1 <- newVar realWorldStatePrimTy ; s2 <- newVar realWorldStatePrimTy @@ -875,9 +877,11 @@ cpeApp top_env expr stateResultAlt stateVar resultVar rhs = (DataAlt (tupleDataCon Unboxed 2), [stateVar, resultVar], rhs) - expr = Case (App k s0) b0 (varType b0) [stateResultAlt s1 y rhs1] - rhs1 = Case (mkApps (Var touchId) [Type arg_ty, x, Var s1]) s1 (varType s1) [(DEFAULT, [], rhs2)] - rhs2 = mkApps (Var $ dataConWrapId $ tupleDataCon Unboxed 2) [Var s2, Var y] + expr = Case (App k s0) b0 out_ty [stateResultAlt s1 y rhs1] + rhs1 = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, x, Var s1] + in Case scrut s2 out_ty [(DEFAULT, [], rhs2)] + rhs2 = mkApps (Var $ dataConWrapId $ tupleDataCon Unboxed 2) + [mkTyArg voidRepTy, mkTyArg result_rep, mkTyArg realWorldStatePrimTy, mkTyArg result_ty, Var s2, Var y] ; cpeBody env expr } cpe_app _env (Var f) args _ ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -104,7 +104,9 @@ lintStgArg (StgLitArg _) = return () lintStgArg (StgVarArg v) = lintStgVar v lintStgVar :: Id -> LintM () -lintStgVar id = checkInScope id +lintStgVar id + | id `hasKey` keepAliveIdKey = addErrL (text "keepAlive# not permitted in STG") + | otherwise = checkInScope id lintStgBinds :: (OutputablePass a, BinderP a ~ Id) ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -539,7 +539,7 @@ data CallMethod getCallMethod :: DynFlags -> Name -- Function being applied - -> Id -- Function Id used to chech if it can refer to + -> Id -- Function Id used to check if it can refer to -- CAF's and whether the function is tail-calling -- itself -> LambdaFormInfo -- Its info @@ -626,7 +626,7 @@ getCallMethod _ _name _ LFLetNoEscape _n_args _v_args (LneLoc blk_id lne_regs) _self_loop_info = JumpToIt blk_id lne_regs -getCallMethod _ _ _ _ _ _ _ _ = panic "Unknown call method" +getCallMethod _ name _ lf_info _ _ _ _ = pprPanic "Unknown call method" (ppr name $$ ppr lf_info) ----------------------------------------------------------------------------- -- Data types for closure information View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b01122e0159f2abeccef0376745e46355501555...b4cb0d769661ea02daca624af15db0bee01d9930 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b01122e0159f2abeccef0376745e46355501555...b4cb0d769661ea02daca624af15db0bee01d9930 You're receiving 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 16 01:42:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 21:42:48 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Work in progress on runRW# Message-ID: <5e97b818165ed_6167134ebbc452187a3@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 354d630c by Simon Peyton Jones at 2020-04-15T21:42:12-04:00 Work in progress on runRW# This is a proof of concept, in progress. It treats runRW# (\s. e) specially in three ways * In the simplifier, we transform K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) where K is a context * In Lint, join points are allowed to occur inside the continuation. join j x = rhs in runRW# (\s. case ... of A -> j 1 B -> ... C -> J 2) Very much as they can occur in other join points. * In OccurAnal, we infer join points using the same rule We get much beter optimisation as a result. Still not finished. E.g. Float out may take runST# (\s. e) and float that lambda out. But really we want to keep that lambda in runST#'s argument, otherwise things that were join point might stop being so. But it's a start - - - - - 4 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - libraries/integer-gmp/src/GHC/Integer/Type.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -678,22 +678,9 @@ lintRhs :: Id -> CoreExpr -> LintM LintedType -- its OccInfo and join-pointer-hood lintRhs bndr rhs | Just arity <- isJoinId_maybe bndr - = lint_join_lams arity arity True rhs + = lintJoinLams arity (Just bndr) rhs | AlwaysTailCalled arity <- tailCallInfo (idOccInfo bndr) - = lint_join_lams arity arity False rhs - where - lint_join_lams 0 _ _ rhs - = lintCoreExpr rhs - - lint_join_lams n tot enforce (Lam var expr) - = lintLambda var $ lint_join_lams (n-1) tot enforce expr - - lint_join_lams n tot True _other - = failWithL $ mkBadJoinArityMsg bndr tot (tot-n) rhs - lint_join_lams _ _ False rhs - = markAllJoinsBad $ lintCoreExpr rhs - -- Future join point, not yet eta-expanded - -- Body is not a tail position + = lintJoinLams arity Nothing rhs -- Allow applications of the data constructor @StaticPtr@ at the top -- but produce errors otherwise. @@ -715,6 +702,18 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go binders0 go _ = markAllJoinsBad $ lintCoreExpr rhs +lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM LintedType +lintJoinLams join_arity enforce rhs + = go join_arity rhs + where + go 0 rhs = lintCoreExpr rhs + go n (Lam var expr) = lintLambda var $ go (n-1) expr + go n _other | Just bndr <- enforce -- Join point with too few RHS lambdas + = failWithL $ mkBadJoinArityMsg bndr join_arity n rhs + | otherwise -- Future join point, not yet eta-expanded + = markAllJoinsBad $ lintCoreExpr rhs + -- Body of lambda is not a tail position + lintIdUnfolding :: Id -> Type -> Unfolding -> LintM () lintIdUnfolding bndr bndr_ty uf | isStableUnfolding uf @@ -854,6 +853,15 @@ lintCoreExpr e@(Let (Rec pairs) body) bndrs = map fst pairs lintCoreExpr e@(App _ _) + | Var fun <- fun + , fun `hasKey` runRWKey + , [arg_ty1, arg_ty2, arg3] <- args + = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 + ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 + ; arg3_ty <- lintJoinLams 1 (Just fun) arg3 + ; lintValApp arg3 fun_ty2 arg3_ty } + + | otherwise = do { fun_ty <- lintCoreFun fun (length args) ; lintCoreArgs fun_ty args } where @@ -2751,11 +2759,11 @@ mkInvalidJoinPointMsg var ty 2 (ppr var <+> dcolon <+> ppr ty) mkBadJoinArityMsg :: Var -> Int -> Int -> CoreExpr -> SDoc -mkBadJoinArityMsg var ar nlams rhs +mkBadJoinArityMsg var ar n rhs = vcat [ text "Join point has too few lambdas", text "Join var:" <+> ppr var, text "Join arity:" <+> ppr ar, - text "Number of lambdas:" <+> ppr nlams, + text "Number of lambdas:" <+> ppr (ar - n), text "Rhs = " <+> ppr rhs ] ===================================== compiler/GHC/Core/Op/OccurAnal.hs ===================================== @@ -39,6 +39,7 @@ import GHC.Types.Demand ( argOneShots, argsOneShots ) import Digraph ( SCC(..), Node(..) , stronglyConnCompFromEdgedVerticesUniq , stronglyConnCompFromEdgedVerticesUniqR ) +import PrelNames( runRWKey ) import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set @@ -1880,8 +1881,12 @@ occAnalApp :: OccEnv -> (UsageDetails, Expr CoreBndr) -- Naked variables (not applied) end up here too occAnalApp env (Var fun, args, ticks) - | null ticks = (all_uds, mkApps fun' args') - | otherwise = (all_uds, mkTicks ticks $ mkApps fun' args') + | fun `hasKey` runRWKey + , [t1, t2, arg] <- args + , let (usage, arg') = occAnalRhs env (Just 1) arg + = (usage, mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']) + | otherwise + = (all_uds, mkTicks ticks $ mkApps fun' args') where (fun', fun_id') = lookupVarEnv (occ_bs_env env) fun `orElse` (Var fun, fun) ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -37,10 +37,12 @@ import GHC.Core.DataCon , StrictnessMark (..) ) import GHC.Core.Op.Monad ( Tick(..), SimplMode(..) ) import GHC.Core +import PrelNames ( runRWKey ) import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Core.Ppr ( pprCoreExpr ) +import GHC.Types.Unique ( hasKey ) import GHC.Core.Unfold import GHC.Core.Utils import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg @@ -1852,6 +1854,20 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_strs = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont +-- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o +-- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` runRWKey + , [ ValArg (Lam s body) + , TyArg {}, TyArg {} ] <- rev_args + = do { (env', s') <- simplLamBndr (zapSubstEnv env) s + ; body' <- simplExprC env' body cont + ; let arg' = Lam s' body' + ty' = contResultType cont + rr' = getRuntimeRep ty' + call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] + ; return (emptyFloats env, call') } + ---------- Try rewrite RULES -------------- -- See Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args ===================================== libraries/integer-gmp/src/GHC/Integer/Type.hs ===================================== @@ -2110,7 +2110,7 @@ liftIO (IO m) = m -- NB: equivalent of GHC.IO.unsafeDupablePerformIO, see notes there runS :: S RealWorld a -> a -runS m = case runRW# m of (# _, a #) -> a +runS m = case runRW# (\s -> m s) of (# _, a #) -> a -- stupid hack fail :: [Char] -> S s a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/354d630c8258e4f81058962a5399036014a5cbd7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/354d630c8258e4f81058962a5399036014a5cbd7 You're receiving 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 16 01:47:15 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 21:47:15 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 2 commits: Fix STG lint Message-ID: <5e97b923c1088_61673f81ef22dee452196c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 33845797 by Ben Gamari at 2020-04-16T01:46:46+00:00 Fix STG lint - - - - - 23744e1d by Ben Gamari at 2020-04-16T01:46:57+00:00 StmToCmm error - - - - - 2 changed files: - compiler/GHC/Stg/Lint.hs - compiler/GHC/StgToCmm/Closure.hs Changes: ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -54,6 +54,8 @@ import ErrUtils ( MsgDoc, Severity(..), mkLocMessage ) import GHC.Core.Type import GHC.Types.RepType import GHC.Types.SrcLoc +import GHC.Types.Unique ( hasKey ) +import PrelNames ( keepAliveIdKey ) import Outputable import GHC.Types.Module ( Module ) import qualified ErrUtils as Err ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -626,7 +626,7 @@ getCallMethod _ _name _ LFLetNoEscape _n_args _v_args (LneLoc blk_id lne_regs) _self_loop_info = JumpToIt blk_id lne_regs -getCallMethod _ name _ lf_info _ _ _ _ = pprPanic "Unknown call method" (ppr name $$ ppr lf_info) +getCallMethod _ name _ lf_info _ _ _ _ = pprPanic "Unknown call method" (ppr name) ----------------------------------------------------------------------------- -- Data types for closure information View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/354d630c8258e4f81058962a5399036014a5cbd7...23744e1d12f09366783c50efefeee466d5a5bf42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/354d630c8258e4f81058962a5399036014a5cbd7...23744e1d12f09366783c50efefeee466d5a5bf42 You're receiving 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 16 01:59:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 15 Apr 2020 21:59:49 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Lint: Fix shadowing Message-ID: <5e97bc15c5b56_616776d1c745221022@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 3f72af5f by Ben Gamari at 2020-04-15T21:57:50-04:00 Lint: Fix shadowing - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -1124,8 +1124,8 @@ lintTyApp fun_ty arg_ty ----------------- lintValApp :: CoreExpr -> LintedType -> LintedType -> LintM LintedType lintValApp arg fun_ty arg_ty - | Just (arg,res) <- splitFunTy_maybe fun_ty - = do { ensureEqTys arg arg_ty err1 + | Just (arg_ty', _res_ty') <- splitFunTy_maybe fun_ty + = do { ensureEqTys arg_ty' arg_ty err1 ; return res } | otherwise = failWithL err2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f72af5f4b764beca6a16229c647f59da9925477 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f72af5f4b764beca6a16229c647f59da9925477 You're receiving 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 16 15:43:45 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 16 Apr 2020 11:43:45 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/inline_div Message-ID: <5e987d314b307_6167134ebbc4528839@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/inline_div at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/inline_div You're receiving 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 16 15:49:50 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 16 Apr 2020 11:49:50 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 2 commits: Fix shadowing Message-ID: <5e987e9e173ec_6167e4e49b4528991d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 936fb080 by Ben Gamari at 2020-04-16T02:18:02+00:00 Fix shadowing - - - - - 790805ec by Ben Gamari at 2020-04-16T02:18:07+00:00 Core Lint logic for keepAlive# - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -861,6 +861,19 @@ lintCoreExpr e@(App _ _) ; arg3_ty <- lintJoinLams 1 (Just fun) arg3 ; lintValApp arg3 fun_ty2 arg3_ty } + | Var fun <- fun + , fun `hasKey` keepAliveIdKey + , [arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5, arg6, arg7] <- args + = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 -- ra :: RuntimeRep + ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 -- a :: TYPE ra + ; fun_ty3 <- lintCoreArg fun_ty2 arg_ty3 -- ro :: RuntimeRep + ; fun_ty4 <- lintCoreArg fun_ty3 arg_ty4 -- o :: TYPE ro + ; fun_ty5 <- lintCoreArg fun_ty4 arg5 -- x :: a + ; arg_ty6 <- lintJoinLams 1 (Just fun) arg6 -- f :: State# RW -> (# State# RW, o #) + ; fun_ty6 <- lintValApp arg6 fun_ty5 arg_ty6 + ; lintCoreArg fun_ty6 arg7 -- s0 :: State# RW + } + | otherwise = do { fun_ty <- lintCoreFun fun (length args) ; lintCoreArgs fun_ty args } @@ -1124,9 +1137,9 @@ lintTyApp fun_ty arg_ty ----------------- lintValApp :: CoreExpr -> LintedType -> LintedType -> LintM LintedType lintValApp arg fun_ty arg_ty - | Just (arg_ty', _res_ty') <- splitFunTy_maybe fun_ty + | Just (arg_ty', res_ty') <- splitFunTy_maybe fun_ty = do { ensureEqTys arg_ty' arg_ty err1 - ; return res } + ; return res_ty' } | otherwise = failWithL err2 where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3f72af5f4b764beca6a16229c647f59da9925477...790805ecc57d1a732efa4baacae1a9ce6c413d6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3f72af5f4b764beca6a16229c647f59da9925477...790805ecc57d1a732efa4baacae1a9ce6c413d6e You're receiving 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 16 15:56:26 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 16 Apr 2020 11:56:26 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] gitlab-ci: Force locale to en_US.UTF-8 Message-ID: <5e98802a8d8e4_6167124c91105291085@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci at Glasgow Haskell Compiler / GHC Commits: f734614b by Ben Gamari at 2020-04-16T11:55:46-04:00 gitlab-ci: Force locale to en_US.UTF-8 - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -26,6 +26,10 @@ LT_CYAN="1;36" WHITE="1;37" LT_GRAY="0;37" +# Global environment +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + # GitLab Pipelines log section delimiters # https://gitlab.com/gitlab-org/gitlab-foss/issues/14664 start_section() { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f734614b01f1ba409f1d2dbc4db0ac630e61c1f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f734614b01f1ba409f1d2dbc4db0ac630e61c1f8 You're receiving 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 16 15:57:45 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 16 Apr 2020 11:57:45 -0400 Subject: [Git][ghc/ghc][wip/T18036] 35 commits: hadrian: Use --export-dynamic when linking iserv Message-ID: <5e988079c10ab_6167e4e49b45291564@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18036 at Glasgow Haskell Compiler / GHC Commits: ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 24d7f2af by Simon Peyton Jones at 2020-04-16T11:57:32-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - 30 changed files: - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/DmdAnal.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs - compiler/ghc.cabal.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/386b5ad22ad8724204be13e29f1e5181574880fa...24d7f2afc4c69976ee4ca6a21cd44c5b496a271d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/386b5ad22ad8724204be13e29f1e5181574880fa...24d7f2afc4c69976ee4ca6a21cd44c5b496a271d You're receiving 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 16 17:01:38 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 16 Apr 2020 13:01:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18065 Message-ID: <5e988f72db90e_6167136dfb9c53116c6@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18065 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18065 You're receiving 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 16 17:12:38 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 16 Apr 2020 13:12:38 -0400 Subject: [Git][ghc/ghc][wip/T18065] Fix #18065 by fixing an InstCo oversight in Core Lint Message-ID: <5e9892061fed6_616765c7a28531583c@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18065 at Glasgow Haskell Compiler / GHC Commits: cde7683b by Ryan Scott at 2020-04-16T13:10:29-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - 3 changed files: - compiler/GHC/Core/Lint.hs - + testsuite/tests/indexed-types/should_compile/T18065.hs - testsuite/tests/indexed-types/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2030,21 +2030,21 @@ lintCoercion the_co@(LRCo lr co) lintCoercion (InstCo co arg) = do { co' <- lintCoercion co ; arg' <- lintCoercion arg - ; let Pair t1' t2' = coercionKind co' - Pair s1 s2 = coercionKind arg + ; let Pair t1 t2 = coercionKind co' + Pair s1 s2 = coercionKind arg' ; lintRole arg Nominal (coercionRole arg') - ; case (splitForAllTy_ty_maybe t1', splitForAllTy_ty_maybe t2') of + ; case (splitForAllTy_ty_maybe t1, splitForAllTy_ty_maybe t2) of -- forall over tvar { (Just (tv1,_), Just (tv2,_)) | typeKind s1 `eqType` tyVarKind tv1 , typeKind s2 `eqType` tyVarKind tv2 -> return (InstCo co' arg') | otherwise - -> failWithL (text "Kind mis-match in inst coercion") + -> failWithL (text "Kind mis-match in inst coercion1" <+> ppr co) - ; _ -> case (splitForAllTy_co_maybe t1', splitForAllTy_co_maybe t2') of + ; _ -> case (splitForAllTy_co_maybe t1, splitForAllTy_co_maybe t2) of -- forall over covar { (Just (cv1, _), Just (cv2, _)) | typeKind s1 `eqType` varType cv1 @@ -2053,7 +2053,7 @@ lintCoercion (InstCo co arg) , CoercionTy _ <- s2 -> return (InstCo co' arg') | otherwise - -> failWithL (text "Kind mis-match in inst coercion") + -> failWithL (text "Kind mis-match in inst coercion2" <+> ppr co) ; _ -> failWithL (text "Bad argument of inst") }}} ===================================== testsuite/tests/indexed-types/should_compile/T18065.hs ===================================== @@ -0,0 +1,108 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +module T18065 where + +import Data.Kind +import Data.List.NonEmpty (NonEmpty(..)) + +type family Sing :: k -> Type +data TyFun :: Type -> Type -> Type +type a ~> b = TyFun a b -> Type +infixr 0 ~> +type family Apply (f :: a ~> b) (x :: a) :: b + +type SingFunction1 f = forall t. Sing t -> Sing (f `Apply` t) +singFun1 :: forall f. SingFunction1 f -> Sing f +singFun1 f = SLambda f + +type SingFunction2 f = forall t1 t2. Sing t1 -> Sing t2 -> Sing (f `Apply` t1 `Apply` t2) +singFun2 :: forall f. SingFunction2 f -> Sing f +singFun2 f = SLambda (\x -> singFun1 (f x)) + +newtype SLambda (f :: a ~> b) = + SLambda { applySing :: forall t. Sing t -> Sing (f `Apply` t) } +type instance Sing = SLambda + +data SList :: forall a. [a] -> Type where + SNil :: SList '[] + SCons :: Sing x -> Sing xs -> SList (x:xs) +type instance Sing = SList + +data SNonEmpty :: forall a. NonEmpty a -> Type where + (:%|) :: Sing x -> Sing xs -> SNonEmpty (x:|xs) +type instance Sing = SNonEmpty + +type family Id (x :: a) :: a where + Id x = x +data IdSym0 :: a ~> a +type instance Apply IdSym0 x = Id x +sId :: forall a (x :: a). Sing x -> Sing (Id x) +sId sx = sx + +type family (.) (f :: b ~> c) (g :: a ~> b) (x :: a) :: c where + (f . g) x = f `Apply` (g `Apply` x) +data (.@#@$) :: (b ~> c) ~> (a ~> b) ~> a ~> c +data (.@#@$$) :: (b ~> c) -> (a ~> b) ~> a ~> c +data (.@#@$$$) :: (b ~> c) -> (a ~> b) -> a ~> c +type instance Apply (.@#@$) f = (.@#@$$) f +type instance Apply ((.@#@$$) f) g = (.@#@$$$) f g +type instance Apply ((.@#@$$$) f g) x = (f . g) x +(%.) :: forall b c a (f :: b ~> c) (g :: a ~> b) (x :: a). + Sing f -> Sing g -> Sing x -> Sing ((f . g) x) +(%.) sf sg sx = sf `applySing` (sg `applySing` sx) + +type family Go (k :: a ~> b ~> b) (z :: b) (l :: [a]) :: b where + Go _ z '[] = z + Go k z (y:ys) = k `Apply` y `Apply` Go k z ys +data GoSym :: (a ~> b ~> b) -> b -> [a] ~> b +type instance Apply (GoSym k z) l = Go k z l +type family Listfoldr (k :: a ~> b ~> b) (z :: b) (l :: [a]) :: b where + Listfoldr k z l = Go k z l +sListfoldr :: forall a b (k :: a ~> b ~> b) (z :: b) (l :: [a]). + Sing k -> Sing z -> Sing l -> Sing (Listfoldr k z l) +sListfoldr sk sz = sGo + where + sGo :: forall l'. Sing l' -> Sing (GoSym k z `Apply` l') + sGo SNil = sz + sGo (sy `SCons` sys) = sk `applySing` sy `applySing` sGo sys + +class PMonoid a where + type Mempty :: a + type Mappend (x :: a) (y :: a) :: a +data MappendSym0 :: a ~> a ~> a +data MappendSym1 :: a -> a ~> a +type instance Apply MappendSym0 x = MappendSym1 x +type instance Apply (MappendSym1 x) y = Mappend x y +class SMonoid a where + sMempty :: Sing (Mempty :: a) + sMappend :: forall (x :: a) (y :: a). Sing x -> Sing y -> Sing (Mappend x y) + +class PFoldable t where + type Foldr (f :: a ~> b ~> b) (z :: b) (l :: t a) :: b +instance PFoldable [] where + type Foldr f z l = Listfoldr f z l +class SFoldable t where + sFoldr :: forall a b (f :: a ~> b ~> b) (z :: b) (l :: t a). + Sing f -> Sing z -> Sing l -> Sing (Foldr f z l) +instance SFoldable [] where + sFoldr = sListfoldr + +type family FoldMap (f :: a ~> m) (l :: t a) :: m where + FoldMap f l = Foldr (MappendSym0 .@#@$$$ f) Mempty l +sFoldMap :: forall t a m (f :: a ~> m) (l :: t a). + (SFoldable t, SMonoid m) + => Sing f -> Sing l -> Sing (FoldMap f l) +sFoldMap sf = sFoldr (singFun2 @((.@#@$$) MappendSym0) (singFun2 @MappendSym0 sMappend %.) `applySing` sf) sMempty + +type family NEFold (l :: NonEmpty m) :: m where + NEFold (a :| as) = a `Mappend` FoldMap IdSym0 as +sNEFold :: forall m (l :: NonEmpty m). SMonoid m + => Sing l -> Sing (NEFold l) +sNEFold (sa :%| sas) = sa `sMappend` sFoldMap (singFun1 @IdSym0 sId) sas ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -295,3 +295,4 @@ test('T17008b', normal, compile, ['']) test('T17056', normal, compile, ['']) test('T17405', normal, multimod_compile, ['T17405c', '-v0']) test('T17923', normal, compile, ['']) +test('T18065', normal, compile, ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cde7683be2c71f6142aa5f39ff18f0ab9a170f75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cde7683be2c71f6142aa5f39ff18f0ab9a170f75 You're receiving 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 16 17:42:10 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Thu, 16 Apr 2020 13:42:10 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 3 commits: Fix #18052 by using pprPrefixOcc in more places Message-ID: <5e9898f21ffbd_616765c7a28531806c@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 5e3b1750 by John Ericson at 2020-04-16T13:42:06-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 30 changed files: - compiler/GHC/Core/Ppr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - rts/ProfHeap.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c8175f9a4b88b62aa3933e97463f89b5f964d1c7...5e3b1750f9395791e274235347700347f411a95a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c8175f9a4b88b62aa3933e97463f89b5f964d1c7...5e3b1750f9395791e274235347700347f411a95a You're receiving 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 17 08:55:38 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 17 Apr 2020 04:55:38 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Fix "build/elem" RULE. Message-ID: <5e996f0a763c4_61673f8199536d94536232c@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: e9d9e1bb by Andreas Klebinger at 2020-04-17T10:53:39+02:00 Fix "build/elem" RULE. An redundant constraint prevented the rule from matching. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. Surprisingly this seems to regress elem for strings. To avoid this we now also allow foldrCString to inline and add an UTF8 variant. This usually results in elem to be compiled to a tight non-allocating loop over the primitive string literal which performs a linear search. In the process this commit adds UTF8 variants for some of the functions in CString. This is required to make this work for both ASCII and UTF8 strings. - - - - - 9 changed files: - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1624,6 +1624,10 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n +"unpack-utf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-list-utf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-append-utf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + -- There's a built-in rule (in GHC.Core.Op.ConstantFold) for -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,7 +1149,7 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} #endif @@ -1174,7 +1174,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -11,7 +11,9 @@ * Add `singleton` function for `Data.List.NonEmpty`. - + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement more often. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,15 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques -dsuppress-all + # All occurences of elem should be optimized away. + # For strings these should result in loops after inlining foldCString. + # For lists it should result in a case expression. + echo $$(cat T17752.dump-simpl | grep "elem" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,18 @@ +module T17752 where + +-- All occurences of elem should be optimized away. +-- For strings these should result in loops after inlining foldCString. +-- For lists it should result in a case expression. + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +isOneOfThese x = x `elem` [1,2,3,4,5::Int] +isNotOneOfThese x = x `notElem` [1,2,3,4,5::Int] + +isElemString x = elem x "foo" +isNotElemString x = notElem x "bar" + +isElemStringUtf x = elem x "foö" +isNotElemStringUtf x = notElem x "bär" ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,2 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) + ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) \ No newline at end of file ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,13 +17,77 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types import GHC.Prim +{- +Note [String literals in GHC] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +String literals get quite a bit of special handling in GHC. This Note +summarises the moving parts. + +* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in + turn calls GHC.Core.Make.mkStringExprFS. + + The desugarer desugars the Haskell literal "foo" into Core + GHC.CString.unpackCString# "foo"# + where "foo"# is primitive string literal (of type Addr#). + + When the string cannot be encoded as a C string, we use UTF8: + GHC.CString.unpackCStringUtf8# "foo"# + +* The library module ghc-prim:GHC.CString has a bunch of functions that + work over primitive strings, including GHC.CString.unpackCString# + +* GHC.Core.Op.ConstantFold has some RULES that optimise certain string + operations on literal strings. For example: + + + Constant folding the desugared form of ("foo" ++ "bar") + into ("foobar") + + Comparing strings + + and more + +* GHC.Base has a number of regular rules for String literals. + + + a rule "eqString": (==) @String = eqString + where GHC.Base.eqString :: String -> String -> Bool + + ConstantFold has a RULE for eqString on literals: + eqString (Lit "foo"#) (Lit "bar"#) --> False + + This allows compile time evaluation of things like "foo" == "bar" + + + A bunch of rules to promote fusion: + + "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) + "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a + "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n + + And UTF8 variants of these rules. + +* We allow primitive (unlifted) literal strings to be top-level + bindings, breaking out usual rule. See GHC.Core + Note [Core top-level string literals] + +* TODO: There is work on a special code-gen path for top-level boxed strings + str :: [Char] + str = unpackCString# "foo"# + so that they can all share a common code pointer + + There is a WIP MR on gitlab for this: !3012 + +-} + ----------------------------------------------------------------------------- -- Unpacking C strings ----------------------------------------------------------------------------- @@ -71,8 +135,27 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Inlining of unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n + +We use NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. + +This can cause a code size increase but it was minimal +when looking at nofib. + +This is especially important for elem which then results in an +allocation free loop. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +172,10 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +198,17 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- See [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +216,43 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +271,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explicit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,15 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + +- unpackFoldrCString* variants can now inline in phase [0]. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9d9e1bb4115a83b0f9130c63f248bc1a97590a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9d9e1bb4115a83b0f9130c63f248bc1a97590a7 You're receiving 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 17 09:35:11 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 17 Apr 2020 05:35:11 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Fix #18052 by using pprPrefixOcc in more places Message-ID: <5e99784f1b5b1_616765c7a28537826b@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 5952a9dd by Sylvain Henry at 2020-04-17T05:35:00-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - eefc926c by Ryan Scott at 2020-04-17T05:35:01-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - 14 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Tc/Module.hs - hadrian/src/Rules/Compile.hs - rts/ProfHeap.c - + testsuite/tests/ghci/should_fail/T18052b.script - + testsuite/tests/ghci/should_fail/T18052b.stderr - testsuite/tests/ghci/should_fail/all.T - + testsuite/tests/indexed-types/should_compile/T18065.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr - + testsuite/tests/printer/T18052a.hs - + testsuite/tests/printer/T18052a.stderr - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2030,21 +2030,21 @@ lintCoercion the_co@(LRCo lr co) lintCoercion (InstCo co arg) = do { co' <- lintCoercion co ; arg' <- lintCoercion arg - ; let Pair t1' t2' = coercionKind co' - Pair s1 s2 = coercionKind arg + ; let Pair t1 t2 = coercionKind co' + Pair s1 s2 = coercionKind arg' ; lintRole arg Nominal (coercionRole arg') - ; case (splitForAllTy_ty_maybe t1', splitForAllTy_ty_maybe t2') of + ; case (splitForAllTy_ty_maybe t1, splitForAllTy_ty_maybe t2) of -- forall over tvar { (Just (tv1,_), Just (tv2,_)) | typeKind s1 `eqType` tyVarKind tv1 , typeKind s2 `eqType` tyVarKind tv2 -> return (InstCo co' arg') | otherwise - -> failWithL (text "Kind mis-match in inst coercion") + -> failWithL (text "Kind mis-match in inst coercion1" <+> ppr co) - ; _ -> case (splitForAllTy_co_maybe t1', splitForAllTy_co_maybe t2') of + ; _ -> case (splitForAllTy_co_maybe t1, splitForAllTy_co_maybe t2) of -- forall over covar { (Just (cv1, _), Just (cv2, _)) | typeKind s1 `eqType` varType cv1 @@ -2053,7 +2053,7 @@ lintCoercion (InstCo co arg) , CoercionTy _ <- s2 -> return (InstCo co' arg') | otherwise - -> failWithL (text "Kind mis-match in inst coercion") + -> failWithL (text "Kind mis-match in inst coercion2" <+> ppr co) ; _ -> failWithL (text "Bad argument of inst") }}} ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -123,11 +123,13 @@ ppr_binding ann (val_bdr, expr) , pp_bind ] where + pp_val_bdr = pprPrefixOcc val_bdr + pp_bind = case bndrIsJoin_maybe val_bdr of Nothing -> pp_normal_bind Just ar -> pp_join_bind ar - pp_normal_bind = hang (ppr val_bdr) 2 (equals <+> pprCoreExpr expr) + pp_normal_bind = hang pp_val_bdr 2 (equals <+> pprCoreExpr expr) -- For a join point of join arity n, we want to print j = \x1 ... xn -> e -- as "j x1 ... xn = e" to differentiate when a join point returns a @@ -135,7 +137,7 @@ ppr_binding ann (val_bdr, expr) -- an n-argument function). pp_join_bind join_arity | bndrs `lengthAtLeast` join_arity - = hang (ppr val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) + = hang (pp_val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) 2 (equals <+> pprCoreExpr rhs) | otherwise -- Yikes! A join-binding with too few lambda -- Lint will complain, but we don't want to crash @@ -164,8 +166,10 @@ ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc -- an atomic value (e.g. function args) ppr_expr add_par (Var name) - | isJoinId name = add_par ((text "jump") <+> ppr name) - | otherwise = ppr name + | isJoinId name = add_par ((text "jump") <+> pp_name) + | otherwise = pp_name + where + pp_name = pprPrefixOcc name ppr_expr add_par (Type ty) = add_par (text "TYPE:" <+> ppr ty) -- Weird ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> ppr co) ppr_expr add_par (Lit lit) = pprLiteral add_par lit @@ -429,7 +433,7 @@ pprKindedTyVarBndr tyvar -- pprIdBndr does *not* print the type -- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness pprIdBndr :: Id -> SDoc -pprIdBndr id = ppr id <+> pprIdBndrInfo (idInfo id) +pprIdBndr id = pprPrefixOcc id <+> pprIdBndrInfo (idInfo id) pprIdBndrInfo :: IdInfo -> SDoc pprIdBndrInfo info ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2122,7 +2122,7 @@ tcRnStmt hsc_env rdr_stmt } where bad_unboxed id = addErr (sep [text "GHCi can't bind a variable of unlifted type:", - nest 2 (ppr id <+> dcolon <+> ppr (idType id))]) + nest 2 (pprPrefixOcc id <+> dcolon <+> ppr (idType id))]) {- -------------------------------------------------------------------------- @@ -2903,7 +2903,7 @@ ppr_types debug type_env -- etc are suppressed (unless -dppr-debug), -- because they appear elsewhere - ppr_sig id = hang (ppr id <+> dcolon) 2 (ppr (tidyTopType (idType id))) + ppr_sig id = hang (pprPrefixOcc id <+> dcolon) 2 (ppr (tidyTopType (idType id))) ppr_tycons :: Bool -> [FamInst] -> TypeEnv -> SDoc ppr_tycons debug fam_insts type_env @@ -2921,7 +2921,7 @@ ppr_tycons debug fam_insts type_env | otherwise = isExternalName (tyConName tycon) && not (tycon `elem` fi_tycons) ppr_tc tc - = vcat [ hang (ppr (tyConFlavour tc) <+> ppr tc + = vcat [ hang (ppr (tyConFlavour tc) <+> pprPrefixOcc (tyConName tc) <> braces (ppr (tyConArity tc)) <+> dcolon) 2 (ppr (tidyTopType (tyConKind tc))) , nest 2 $ @@ -2955,7 +2955,7 @@ ppr_patsyns type_env = ppr_things "PATTERN SYNONYMS" ppr_ps (typeEnvPatSyns type_env) where - ppr_ps ps = ppr ps <+> dcolon <+> pprPatSynType ps + ppr_ps ps = pprPrefixOcc ps <+> dcolon <+> pprPatSynType ps ppr_insts :: [ClsInst] -> SDoc ppr_insts ispecs ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -55,7 +55,22 @@ compilePackage rs = do &%> \ [dyn_o, _dyn_hi] -> do p <- platformSupportsSharedLibs if p - then need [dyn_o -<.> "o", dyn_o -<.> "hi"] + then do + -- We `need` ".o/.hi" because GHC is called with `-dynamic-too` + -- and builds ".dyn_o/.dyn_hi" too. + changed <- needHasChanged [dyn_o -<.> "o", dyn_o -<.> "hi"] + + -- If for some reason a previous Hadrian execution has been + -- interrupted after the rule for .o/.hi generation has completed + -- but before the current rule for .dyn_o/.dyn_hi has completed, + -- or if some of the dynamic artifacts have been removed by the + -- user, "needing" the non dynamic artifacts is not enough as + -- Shake won't execute the associated action. Hence we detect + -- this case and we explictly build the dynamic artifacts here: + case changed of + [] -> compileHsObjectAndHi rs dyn_o + _ -> pure () + else compileHsObjectAndHi rs dyn_o forM_ ((,) <$> hsExts <*> wayPats) $ \ ((oExt, hiExt), wayPat) -> ===================================== rts/ProfHeap.c ===================================== @@ -552,8 +552,6 @@ initHeapProfiling(void) void endHeapProfiling(void) { - StgDouble seconds; - if (! RtsFlags.ProfFlags.doHeapProfile) { return; } @@ -596,7 +594,10 @@ endHeapProfiling(void) stgFree(censuses); - seconds = mut_user_time(); + RTSStats stats; + getRTSStats(&stats); + Time mut_time = stats.mutator_cpu_ns; + StgDouble seconds = TimeToSecondsDbl(mut_time); printSample(true, seconds); printSample(false, seconds); fclose(hp_file); ===================================== testsuite/tests/ghci/should_fail/T18052b.script ===================================== @@ -0,0 +1,2 @@ +:set -XMagicHash +let (%%%) = 1# ===================================== testsuite/tests/ghci/should_fail/T18052b.stderr ===================================== @@ -0,0 +1,3 @@ + +:1:1: error: + GHCi can't bind a variable of unlifted type: (%%%) :: GHC.Prim.Int# ===================================== testsuite/tests/ghci/should_fail/all.T ===================================== @@ -3,3 +3,4 @@ test('T10549a', [], ghci_script, ['T10549a.script']) test('T15055', normalise_version('ghc'), ghci_script, ['T15055.script']) test('T16013', [], ghci_script, ['T16013.script']) test('T16287', [], ghci_script, ['T16287.script']) +test('T18052b', [], ghci_script, ['T18052b.script']) ===================================== testsuite/tests/indexed-types/should_compile/T18065.hs ===================================== @@ -0,0 +1,108 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +module T18065 where + +import Data.Kind +import Data.List.NonEmpty (NonEmpty(..)) + +type family Sing :: k -> Type +data TyFun :: Type -> Type -> Type +type a ~> b = TyFun a b -> Type +infixr 0 ~> +type family Apply (f :: a ~> b) (x :: a) :: b + +type SingFunction1 f = forall t. Sing t -> Sing (f `Apply` t) +singFun1 :: forall f. SingFunction1 f -> Sing f +singFun1 f = SLambda f + +type SingFunction2 f = forall t1 t2. Sing t1 -> Sing t2 -> Sing (f `Apply` t1 `Apply` t2) +singFun2 :: forall f. SingFunction2 f -> Sing f +singFun2 f = SLambda (\x -> singFun1 (f x)) + +newtype SLambda (f :: a ~> b) = + SLambda { applySing :: forall t. Sing t -> Sing (f `Apply` t) } +type instance Sing = SLambda + +data SList :: forall a. [a] -> Type where + SNil :: SList '[] + SCons :: Sing x -> Sing xs -> SList (x:xs) +type instance Sing = SList + +data SNonEmpty :: forall a. NonEmpty a -> Type where + (:%|) :: Sing x -> Sing xs -> SNonEmpty (x:|xs) +type instance Sing = SNonEmpty + +type family Id (x :: a) :: a where + Id x = x +data IdSym0 :: a ~> a +type instance Apply IdSym0 x = Id x +sId :: forall a (x :: a). Sing x -> Sing (Id x) +sId sx = sx + +type family (.) (f :: b ~> c) (g :: a ~> b) (x :: a) :: c where + (f . g) x = f `Apply` (g `Apply` x) +data (.@#@$) :: (b ~> c) ~> (a ~> b) ~> a ~> c +data (.@#@$$) :: (b ~> c) -> (a ~> b) ~> a ~> c +data (.@#@$$$) :: (b ~> c) -> (a ~> b) -> a ~> c +type instance Apply (.@#@$) f = (.@#@$$) f +type instance Apply ((.@#@$$) f) g = (.@#@$$$) f g +type instance Apply ((.@#@$$$) f g) x = (f . g) x +(%.) :: forall b c a (f :: b ~> c) (g :: a ~> b) (x :: a). + Sing f -> Sing g -> Sing x -> Sing ((f . g) x) +(%.) sf sg sx = sf `applySing` (sg `applySing` sx) + +type family Go (k :: a ~> b ~> b) (z :: b) (l :: [a]) :: b where + Go _ z '[] = z + Go k z (y:ys) = k `Apply` y `Apply` Go k z ys +data GoSym :: (a ~> b ~> b) -> b -> [a] ~> b +type instance Apply (GoSym k z) l = Go k z l +type family Listfoldr (k :: a ~> b ~> b) (z :: b) (l :: [a]) :: b where + Listfoldr k z l = Go k z l +sListfoldr :: forall a b (k :: a ~> b ~> b) (z :: b) (l :: [a]). + Sing k -> Sing z -> Sing l -> Sing (Listfoldr k z l) +sListfoldr sk sz = sGo + where + sGo :: forall l'. Sing l' -> Sing (GoSym k z `Apply` l') + sGo SNil = sz + sGo (sy `SCons` sys) = sk `applySing` sy `applySing` sGo sys + +class PMonoid a where + type Mempty :: a + type Mappend (x :: a) (y :: a) :: a +data MappendSym0 :: a ~> a ~> a +data MappendSym1 :: a -> a ~> a +type instance Apply MappendSym0 x = MappendSym1 x +type instance Apply (MappendSym1 x) y = Mappend x y +class SMonoid a where + sMempty :: Sing (Mempty :: a) + sMappend :: forall (x :: a) (y :: a). Sing x -> Sing y -> Sing (Mappend x y) + +class PFoldable t where + type Foldr (f :: a ~> b ~> b) (z :: b) (l :: t a) :: b +instance PFoldable [] where + type Foldr f z l = Listfoldr f z l +class SFoldable t where + sFoldr :: forall a b (f :: a ~> b ~> b) (z :: b) (l :: t a). + Sing f -> Sing z -> Sing l -> Sing (Foldr f z l) +instance SFoldable [] where + sFoldr = sListfoldr + +type family FoldMap (f :: a ~> m) (l :: t a) :: m where + FoldMap f l = Foldr (MappendSym0 .@#@$$$ f) Mempty l +sFoldMap :: forall t a m (f :: a ~> m) (l :: t a). + (SFoldable t, SMonoid m) + => Sing f -> Sing l -> Sing (FoldMap f l) +sFoldMap sf = sFoldr (singFun2 @((.@#@$$) MappendSym0) (singFun2 @MappendSym0 sMappend %.) `applySing` sf) sMempty + +type family NEFold (l :: NonEmpty m) :: m where + NEFold (a :| as) = a `Mappend` FoldMap IdSym0 as +sNEFold :: forall m (l :: NonEmpty m). SMonoid m + => Sing l -> Sing (NEFold l) +sNEFold (sa :%| sas) = sa `sMappend` sFoldMap (singFun1 @IdSym0 sId) sas ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -295,3 +295,4 @@ test('T17008b', normal, compile, ['']) test('T17056', normal, compile, ['']) test('T17405', normal, multimod_compile, ['T17405c', '-v0']) test('T17923', normal, compile, ['']) +test('T18065', normal, compile, ['-O']) ===================================== testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr ===================================== @@ -1,28 +1,28 @@ TYPE SIGNATURES - !! :: forall {a}. [a] -> Int -> a - $ :: forall {a} {b}. (a -> b) -> a -> b - $! :: forall {a} {b}. (a -> b) -> a -> b - && :: Bool -> Bool -> Bool - * :: forall {a}. Num a => a -> a -> a - ** :: forall {a}. Floating a => a -> a -> a - + :: forall {a}. Num a => a -> a -> a - ++ :: forall {a}. [a] -> [a] -> [a] - - :: forall {a}. Num a => a -> a -> a - . :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c - / :: forall {a}. Fractional a => a -> a -> a - /= :: forall {a}. Eq a => a -> a -> Bool - < :: forall {a}. Ord a => a -> a -> Bool - <= :: forall {a}. Ord a => a -> a -> Bool - =<< :: + (!!) :: forall {a}. [a] -> Int -> a + ($) :: forall {a} {b}. (a -> b) -> a -> b + ($!) :: forall {a} {b}. (a -> b) -> a -> b + (&&) :: Bool -> Bool -> Bool + (*) :: forall {a}. Num a => a -> a -> a + (**) :: forall {a}. Floating a => a -> a -> a + (+) :: forall {a}. Num a => a -> a -> a + (++) :: forall {a}. [a] -> [a] -> [a] + (-) :: forall {a}. Num a => a -> a -> a + (.) :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c + (/) :: forall {a}. Fractional a => a -> a -> a + (/=) :: forall {a}. Eq a => a -> a -> Bool + (<) :: forall {a}. Ord a => a -> a -> Bool + (<=) :: forall {a}. Ord a => a -> a -> Bool + (=<<) :: forall {m :: * -> *} {a} {b}. Monad m => (a -> m b) -> m a -> m b - == :: forall {a}. Eq a => a -> a -> Bool - > :: forall {a}. Ord a => a -> a -> Bool - >= :: forall {a}. Ord a => a -> a -> Bool - >> :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b - >>= :: + (==) :: forall {a}. Eq a => a -> a -> Bool + (>) :: forall {a}. Ord a => a -> a -> Bool + (>=) :: forall {a}. Ord a => a -> a -> Bool + (>>) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b + (>>=) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> (a -> m b) -> m b - ^ :: forall {b} {a}. (Integral b, Num a) => a -> b -> a - ^^ :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a + (^) :: forall {b} {a}. (Integral b, Num a) => a -> b -> a + (^^) :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a abs :: forall {a}. Num a => a -> a acos :: forall {a}. Floating a => a -> a acosh :: forall {a}. Floating a => a -> a @@ -234,7 +234,7 @@ TYPE SIGNATURES zipWith3 :: forall {a} {b} {c} {d}. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] - || :: Bool -> Bool -> Bool + (||) :: Bool -> Bool -> Bool Dependent modules: [] -Dependent packages: [base-4.13.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeOperators #-} +module T18052a where + +(+++) = (++) +pattern x :||: y = (x,y) +type (^^^) = Either +data (&&&) ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -0,0 +1,42 @@ +TYPE SIGNATURES + (+++) :: forall {a}. [a] -> [a] -> [a] +TYPE CONSTRUCTORS + data type (&&&){0} :: * + type synonym (^^^){0} :: * -> * -> * +PATTERN SYNONYMS + (:||:) :: forall {a} {b}. a -> b -> (a, b) +Dependent modules: [] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 18, types: 53, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) +[GblId, Arity=2, Unf=OtherCon []] +T18052a.$b:||: = GHC.Tuple.(,) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +(+++) :: forall {a}. [a] -> [a] -> [a] +[GblId] +(+++) = (++) + +-- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +T18052a.$m:||: + :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. + (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r +[GblId, Arity=3, Unf=OtherCon []] +T18052a.$m:||: + = \ (@(rep :: GHC.Types.RuntimeRep)) + (@(r :: TYPE rep)) + (@a) + (@b) + (scrut :: (a, b)) + (cont :: a -> b -> r) + _ [Occ=Dead] -> + case scrut of { (x, y) -> cont x y } + + + ===================================== testsuite/tests/printer/all.T ===================================== @@ -57,3 +57,5 @@ test('T14306', ignore_stderr, makefile_test, ['T14306']) test('T14343', normal, compile_fail, ['']) test('T14343b', normal, compile_fail, ['']) test('T15761', normal, compile_fail, ['']) +test('T18052a', normal, compile, + ['-ddump-simpl -ddump-types -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5fddb249ce819c5d3aa9a33a63e99f8042a0ced...eefc926c0871224d2679e8eb6534c5335a3409d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5fddb249ce819c5d3aa9a33a63e99f8042a0ced...eefc926c0871224d2679e8eb6534c5335a3409d6 You're receiving 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 17 10:46:12 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 17 Apr 2020 06:46:12 -0400 Subject: [Git][ghc/ghc][wip/andreask/inline_div] Always inline divInt and modInt in phase zero. Message-ID: <5e9988f48439d_6167134ebbc45387098@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inline_div at Glasgow Haskell Compiler / GHC Commits: c77b9961 by Andreas Klebinger at 2020-04-17T12:44:13+02:00 Always inline divInt and modInt in phase zero. This prevents the overhead of a function call for operations which really only need to be a few instructions. By always inlining them in phase zero we can: * Match on them via rules in earlier phases. * Can constant fold on them in phase zero by rules on their underlying primitives. This fixes #18067 - - - - - 1 changed file: - libraries/ghc-prim/GHC/Classes.hs Changes: ===================================== libraries/ghc-prim/GHC/Classes.hs ===================================== @@ -545,8 +545,8 @@ not False = True -- put them -- These functions have built-in rules. -{-# NOINLINE [0] divInt# #-} -{-# NOINLINE [0] modInt# #-} +{-# INLINE [0] divInt# #-} +{-# INLINE [0] modInt# #-} divInt# :: Int# -> Int# -> Int# x# `divInt#` y# -- Be careful NOT to overflow if we do any additional arithmetic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c77b99613a4e4e1ecb41ae4e98a15932d41ebb99 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c77b99613a4e4e1ecb41ae4e98a15932d41ebb99 You're receiving 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 17 10:56:48 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 17 Apr 2020 06:56:48 -0400 Subject: [Git][ghc/ghc][wip/andreask/inline_div] Always inline divInt and modInt in phase zero. Message-ID: <5e998b70c895a_6167134ebbc45387389@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inline_div at Glasgow Haskell Compiler / GHC Commits: 062201da by Andreas Klebinger at 2020-04-17T12:56:35+02:00 Always inline divInt and modInt in phase zero. This prevents the overhead of a function call for operations which really only need to be a few instructions. By always inlining them in phase zero we can: * Match on them via rules in earlier phases. * Can constant fold on them in phase zero by rules on their underlying primitives. This fixes #18067 - - - - - 2 changed files: - libraries/base/GHC/Base.hs - libraries/ghc-prim/GHC/Classes.hs Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1545,9 +1545,34 @@ getTag x = dataToTag# x -- Definitions of the boxed PrimOps; these will be -- used in the case of partial applications, etc. +{- Note [Inlining divInt, modInt] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + divInt and modInt are implemented in terms of + the quotInt#/remInt# primOps. + + My marking them as INLINE[0] we achieve two things: + + * We can match on them in the early phases via rules. + * We can constant fold via rules on quotInt#/remInt# in + phase zero if they are applied to constants. + + This solves #18067 where we observed divInt ending up + as a uninlined call at times. + + TODO: It might be good to apply the same pattern to + quotRemInt and divModInt. But I have not looked at this + yet. + +-} + {-# INLINE quotInt #-} {-# INLINE remInt #-} +-- See Note [Inlining divInt, modInt] +{-# INLINE[0] divInt #-} +{-# INLINE[0] modInt #-} + quotInt, remInt, divInt, modInt :: Int -> Int -> Int (I# x) `quotInt` (I# y) = I# (x `quotInt#` y) (I# x) `remInt` (I# y) = I# (x `remInt#` y) ===================================== libraries/ghc-prim/GHC/Classes.hs ===================================== @@ -545,8 +545,8 @@ not False = True -- put them -- These functions have built-in rules. -{-# NOINLINE [0] divInt# #-} -{-# NOINLINE [0] modInt# #-} +{-# INLINE [0] divInt# #-} +{-# INLINE [0] modInt# #-} divInt# :: Int# -> Int# -> Int# x# `divInt#` y# -- Be careful NOT to overflow if we do any additional arithmetic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/062201daeadfd2c273ab256be70a22114be3a7e3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/062201daeadfd2c273ab256be70a22114be3a7e3 You're receiving 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 17 11:04:30 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 17 Apr 2020 07:04:30 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Fix "build/elem" RULE. Message-ID: <5e998d3e49b9b_6167124c911053901c@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 776113d9 by Andreas Klebinger at 2020-04-17T13:04:17+02:00 Fix "build/elem" RULE. An redundant constraint prevented the rule from matching. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. Surprisingly this seems to regress elem for strings. To avoid this we now also allow foldrCString to inline and add an UTF8 variant. This usually results in elem to be compiled to a tight non-allocating loop over the primitive string literal which performs a linear search. In the process this commit adds UTF8 variants for some of the functions in CString. This is required to make this work for both ASCII and UTF8 strings. - - - - - 9 changed files: - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1624,6 +1624,10 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n +"unpack-utf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-list-utf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-append-utf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + -- There's a built-in rule (in GHC.Core.Op.ConstantFold) for -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,7 +1149,7 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} #endif @@ -1174,7 +1174,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -11,7 +11,9 @@ * Add `singleton` function for `Data.List.NonEmpty`. - + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement more often. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,15 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques -dsuppress-all + # All occurences of elem should be optimized away. + # For strings these should result in loops after inlining foldCString. + # For lists it should result in a case expression. + echo $$(cat T17752.dump-simpl | grep "elem" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,18 @@ +module T17752 where + +-- All occurences of elem should be optimized away. +-- For strings these should result in loops after inlining foldCString. +-- For lists it should result in a case expression. + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +isOneOfThese x = x `elem` [1,2,3,4,5::Int] +isNotOneOfThese x = x `notElem` [1,2,3,4,5::Int] + +isElemString x = elem x "foo" +isNotElemString x = notElem x "bar" + +isElemStringUtf x = elem x "foö" +isNotElemStringUtf x = notElem x "bär" ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,2 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) + ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,13 +17,77 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types import GHC.Prim +{- +Note [String literals in GHC] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +String literals get quite a bit of special handling in GHC. This Note +summarises the moving parts. + +* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in + turn calls GHC.Core.Make.mkStringExprFS. + + The desugarer desugars the Haskell literal "foo" into Core + GHC.CString.unpackCString# "foo"# + where "foo"# is primitive string literal (of type Addr#). + + When the string cannot be encoded as a C string, we use UTF8: + GHC.CString.unpackCStringUtf8# "foo"# + +* The library module ghc-prim:GHC.CString has a bunch of functions that + work over primitive strings, including GHC.CString.unpackCString# + +* GHC.Core.Op.ConstantFold has some RULES that optimise certain string + operations on literal strings. For example: + + + Constant folding the desugared form of ("foo" ++ "bar") + into ("foobar") + + Comparing strings + + and more + +* GHC.Base has a number of regular rules for String literals. + + + a rule "eqString": (==) @String = eqString + where GHC.Base.eqString :: String -> String -> Bool + + ConstantFold has a RULE for eqString on literals: + eqString (Lit "foo"#) (Lit "bar"#) --> False + + This allows compile time evaluation of things like "foo" == "bar" + + + A bunch of rules to promote fusion: + + "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) + "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a + "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n + + And UTF8 variants of these rules. + +* We allow primitive (unlifted) literal strings to be top-level + bindings, breaking out usual rule. See GHC.Core + Note [Core top-level string literals] + +* TODO: There is work on a special code-gen path for top-level boxed strings + str :: [Char] + str = unpackCString# "foo"# + so that they can all share a common code pointer + + There is a WIP MR on gitlab for this: !3012 + +-} + ----------------------------------------------------------------------------- -- Unpacking C strings ----------------------------------------------------------------------------- @@ -71,8 +135,27 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Inlining of unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n + +We use NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. + +This can cause a code size increase but it was minimal +when looking at nofib. + +This is especially important for elem which then results in an +allocation free loop. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +172,10 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +198,17 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- See [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +216,43 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +271,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explicit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,15 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + +- unpackFoldrCString* variants can now inline in phase [0]. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/776113d9ea70abce8b8e839cc13bad605d6bec8f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/776113d9ea70abce8b8e839cc13bad605d6bec8f You're receiving 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 17 14:09:55 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 17 Apr 2020 10:09:55 -0400 Subject: [Git][ghc/ghc][wip/freebsd-ci] Deleted 1 commit: gitlab-ci: Force locale to en_US.UTF-8 Message-ID: <5e99b8b36cedf_61673f8199536d94541383a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/freebsd-ci 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: f734614b by Ben Gamari at 2020-04-16T11:55:46-04:00 gitlab-ci: Force locale to en_US.UTF-8 - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -26,6 +26,10 @@ LT_CYAN="1;36" WHITE="1;37" LT_GRAY="0;37" +# Global environment +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + # GitLab Pipelines log section delimiters # https://gitlab.com/gitlab-org/gitlab-foss/issues/14664 start_section() { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f734614b01f1ba409f1d2dbc4db0ac630e61c1f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f734614b01f1ba409f1d2dbc4db0ac630e61c1f8 You're receiving 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 17 14:37:14 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 17 Apr 2020 10:37:14 -0400 Subject: [Git][ghc/ghc][wip/T17173] 3 commits: Fix #18052 by using pprPrefixOcc in more places Message-ID: <5e99bf1a9965a_616713503ee05421350@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 2e961b7e by Simon Peyton Jones at 2020-04-17T15:16:32+01:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat - - - - - 30 changed files: - compiler/GHC/Core/Ppr.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Instantiate.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Zonk.hs - libraries/base/tests/T9681.stderr - rts/ProfHeap.c - testsuite/tests/ado/T13242a.stderr - testsuite/tests/ado/ado002.stderr - testsuite/tests/annotations/should_fail/annfail08.stderr - testsuite/tests/driver/T2182.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/27399067b5ff7c335e5bf1f2bc7490f8f8e5027d...2e961b7e52bfa90f405945ba211c48ed1ed9860b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/27399067b5ff7c335e5bf1f2bc7490f8f8e5027d...2e961b7e52bfa90f405945ba211c48ed1ed9860b You're receiving 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 17 14:48:37 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 17 Apr 2020 10:48:37 -0400 Subject: [Git][ghc/ghc][wip/T18008] 3 commits: Fix #18052 by using pprPrefixOcc in more places Message-ID: <5e99c1c5aa1f0_61673f8198ee100c54249b4@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18008 at Glasgow Haskell Compiler / GHC Commits: 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 658bda51 by Simon Peyton Jones at 2020-04-17T15:48:22+01:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 14 changed files: - compiler/GHC/Core/Ppr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Module.hs - rts/ProfHeap.c - + testsuite/tests/ghci/should_fail/T18052b.script - + testsuite/tests/ghci/should_fail/T18052b.stderr - testsuite/tests/ghci/should_fail/all.T - testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr - + testsuite/tests/partial-sigs/should_compile/T18008.hs - + testsuite/tests/partial-sigs/should_compile/T18008.stderr - testsuite/tests/partial-sigs/should_compile/all.T - + testsuite/tests/printer/T18052a.hs - + testsuite/tests/printer/T18052a.stderr - testsuite/tests/printer/all.T Changes: ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -123,11 +123,13 @@ ppr_binding ann (val_bdr, expr) , pp_bind ] where + pp_val_bdr = pprPrefixOcc val_bdr + pp_bind = case bndrIsJoin_maybe val_bdr of Nothing -> pp_normal_bind Just ar -> pp_join_bind ar - pp_normal_bind = hang (ppr val_bdr) 2 (equals <+> pprCoreExpr expr) + pp_normal_bind = hang pp_val_bdr 2 (equals <+> pprCoreExpr expr) -- For a join point of join arity n, we want to print j = \x1 ... xn -> e -- as "j x1 ... xn = e" to differentiate when a join point returns a @@ -135,7 +137,7 @@ ppr_binding ann (val_bdr, expr) -- an n-argument function). pp_join_bind join_arity | bndrs `lengthAtLeast` join_arity - = hang (ppr val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) + = hang (pp_val_bdr <+> sep (map (pprBndr LambdaBind) lhs_bndrs)) 2 (equals <+> pprCoreExpr rhs) | otherwise -- Yikes! A join-binding with too few lambda -- Lint will complain, but we don't want to crash @@ -164,8 +166,10 @@ ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc -- an atomic value (e.g. function args) ppr_expr add_par (Var name) - | isJoinId name = add_par ((text "jump") <+> ppr name) - | otherwise = ppr name + | isJoinId name = add_par ((text "jump") <+> pp_name) + | otherwise = pp_name + where + pp_name = pprPrefixOcc name ppr_expr add_par (Type ty) = add_par (text "TYPE:" <+> ppr ty) -- Weird ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> ppr co) ppr_expr add_par (Lit lit) = pprLiteral add_par lit @@ -429,7 +433,7 @@ pprKindedTyVarBndr tyvar -- pprIdBndr does *not* print the type -- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness pprIdBndr :: Id -> SDoc -pprIdBndr id = ppr id <+> pprIdBndrInfo (idInfo id) +pprIdBndr id = pprPrefixOcc id <+> pprIdBndrInfo (idInfo id) pprIdBndrInfo :: IdInfo -> SDoc pprIdBndrInfo info ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -732,6 +732,7 @@ tc_hs_type mode forall@(HsForAllTy { hst_fvf = fvf, hst_bndrs = hs_tvs m_telescope = Just (sep (map ppr hs_tvs)) ; emitResidualTvConstraint skol_info m_telescope tvs' tclvl wanted + -- See Note [Skolem escape and forall-types] ; return (mkForAllTys bndrs ty') } @@ -920,6 +921,26 @@ under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types +Note [Skolem escape and forall-types] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + f :: forall a. (forall kb (b :: kb). Proxy '[a, b]) -> () + +The Proxy '[a,b] forces a and b to have the same kind. But a's +kind must be bound outside the 'forall a', and hence escapes. +We discover this by building an implication constraint for +each forall. So the inner implication constraint will look like + forall kb (b::kb). kb ~ ka +where ka is a's kind. We can't unify these two, /even/ if ka is +unification variable, because it would be untouchable inside +this inner implication. + +That's what the pushLevelAndCaptureConstraints, plus subsequent +emitResidualTvConstraint is all about, when kind-checking +HsForAllTy. + +Note that we don't need to /simplify/ the constraints here +because we aren't generalising. We just capture them. -} {- ********************************************************************* @@ -2819,10 +2840,13 @@ kindGeneralizeAll ty = do { traceTc "kindGeneralizeAll" empty ; kindGeneralizeSome (const True) ty } -- | Specialized version of 'kindGeneralizeSome', but where no variables --- can be generalized. Use this variant when it is unknowable whether metavariables --- might later be constrained. --- See Note [Recipe for checking a signature] for why and where this --- function is needed. +-- can be generalized, but perhaps some may neeed to be promoted. +-- Use this variant when it is unknowable whether metavariables might +-- later be constrained. +-- +-- To see why this promotion is needed, see +-- Note [Recipe for checking a signature], and especially +-- Note [Promotion in signatures]. kindGeneralizeNone :: TcType -- needn't be zonked -> TcM () kindGeneralizeNone ty @@ -3160,7 +3184,7 @@ tcHsPartialSigType ctxt sig_ty ; return (wcs, wcx, theta, tau) } - -- No kind-generalization here: + -- No kind-generalization here, but perhaps some promotion ; kindGeneralizeNone (mkSpecForAllTys implicit_tvs $ mkSpecForAllTys explicit_tvs $ mkPhiTy theta $ @@ -3171,6 +3195,14 @@ tcHsPartialSigType ctxt sig_ty -- See Note [Extra-constraint holes in partial type signatures] ; emitNamedWildCardHoleConstraints wcs + -- Zonk, so that any nested foralls can "see" their occurrences + -- See Note [Checking partial type signatures], in + -- the bullet on Nested foralls. + ; implicit_tvs <- mapM zonkTcTyVarToTyVar implicit_tvs + ; explicit_tvs <- mapM zonkTcTyVarToTyVar explicit_tvs + ; theta <- mapM zonkTcType theta + ; tau <- zonkTcType tau + -- We return a proper (Name,TyVar) environment, to be sure that -- we bring the right name into scope in the function body. -- Test case: partial-sigs/should_compile/LocalDefinitionBug @@ -3179,7 +3211,7 @@ tcHsPartialSigType ctxt sig_ty -- NB: checkValidType on the final inferred type will be -- done later by checkInferredPolyId. We can't do it - -- here because we don't have a complete tuype to check + -- here because we don't have a complete type to check ; traceTc "tcHsPartialSigType" (ppr tv_prs) ; return (wcs, wcx, tv_prs, theta, tau) } @@ -3198,12 +3230,31 @@ tcPartialContext hs_theta {- Note [Checking partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See also Note [Recipe for checking a signature] +This Note is about tcHsPartialSigType. See also +Note [Recipe for checking a signature] When we have a partial signature like - f,g :: forall a. a -> _ + f :: forall a. a -> _ we do the following +* tcHsPartialSigType does not make quantified type (forall a. blah) + and then instantiate it -- it makes no sense to instantiate a type + with wildcards in it. Rather, tcHsPartialSigType just returns the + 'a' and the 'blah' separately. + + Nor, for the same reason, do we push a level in tcHsPartialSigType. + +* We instantiate 'a' to a unification variable, a TyVarTv, and /not/ + a skolem; hence the "_Tv" in bindExplicitTKBndrs_Tv. Consider + f :: forall a. a -> _ + g :: forall b. _ -> b + f = g + g = f + They are typechecked as a recursive group, with monomorphic types, + so 'a' and 'b' will get unified together. Very like kind inference + for mutually recursive data types (sans CUSKs or SAKS); see + Note [Cloning for tyvar binders] in GHC.Tc.Gen.HsType + * In GHC.Tc.Gen.Sig.tcUserSigType we return a PartialSig, which (unlike the companion CompleteSig) contains the original, as-yet-unchecked source-code LHsSigWcType @@ -3218,12 +3269,28 @@ we do the following g x = True It's really as if we'd written two distinct signatures. -* Note that we don't make quantified type (forall a. blah) and then - instantiate it -- it makes no sense to instantiate a type with - wildcards in it. Rather, tcHsPartialSigType just returns the - 'a' and the 'blah' separately. - - Nor, for the same reason, do we push a level in tcHsPartialSigType. +* Nested foralls. Consider + f :: forall b. (forall a. a -> _) -> b + We do /not/ allow the "_" to be instantiated to 'a'; but we do + (as before) allow it to be instantiated to the (top level) 'b'. + Why not? Because suppose + f x = (x True, x 'c') + We must instantiate that (forall a. a -> _) when typechecking + f's body, so we must know precisely where all the a's are; they + must not be hidden under (filled-in) unification variables! + + We achieve this in the usual way: we push a level at a forall, + so now the unification variable for the "_" can't unify with + 'a'. + +* Just as for ordinary signatures, we must zonk the type after + kind-checking it, to ensure that all the nested forall binders can + see their occurrenceds + + Just as for ordinary signatures, this zonk also gets any Refl casts + out of the way of instantiation. Example: #18008 had + foo :: (forall a. (Show a => blah) |> Refl) -> _ + and that Refl cast messed things up. See #18062. Note [Extra-constraint holes in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2122,7 +2122,7 @@ tcRnStmt hsc_env rdr_stmt } where bad_unboxed id = addErr (sep [text "GHCi can't bind a variable of unlifted type:", - nest 2 (ppr id <+> dcolon <+> ppr (idType id))]) + nest 2 (pprPrefixOcc id <+> dcolon <+> ppr (idType id))]) {- -------------------------------------------------------------------------- @@ -2903,7 +2903,7 @@ ppr_types debug type_env -- etc are suppressed (unless -dppr-debug), -- because they appear elsewhere - ppr_sig id = hang (ppr id <+> dcolon) 2 (ppr (tidyTopType (idType id))) + ppr_sig id = hang (pprPrefixOcc id <+> dcolon) 2 (ppr (tidyTopType (idType id))) ppr_tycons :: Bool -> [FamInst] -> TypeEnv -> SDoc ppr_tycons debug fam_insts type_env @@ -2921,7 +2921,7 @@ ppr_tycons debug fam_insts type_env | otherwise = isExternalName (tyConName tycon) && not (tycon `elem` fi_tycons) ppr_tc tc - = vcat [ hang (ppr (tyConFlavour tc) <+> ppr tc + = vcat [ hang (ppr (tyConFlavour tc) <+> pprPrefixOcc (tyConName tc) <> braces (ppr (tyConArity tc)) <+> dcolon) 2 (ppr (tidyTopType (tyConKind tc))) , nest 2 $ @@ -2955,7 +2955,7 @@ ppr_patsyns type_env = ppr_things "PATTERN SYNONYMS" ppr_ps (typeEnvPatSyns type_env) where - ppr_ps ps = ppr ps <+> dcolon <+> pprPatSynType ps + ppr_ps ps = pprPrefixOcc ps <+> dcolon <+> pprPatSynType ps ppr_insts :: [ClsInst] -> SDoc ppr_insts ispecs ===================================== rts/ProfHeap.c ===================================== @@ -552,8 +552,6 @@ initHeapProfiling(void) void endHeapProfiling(void) { - StgDouble seconds; - if (! RtsFlags.ProfFlags.doHeapProfile) { return; } @@ -596,7 +594,10 @@ endHeapProfiling(void) stgFree(censuses); - seconds = mut_user_time(); + RTSStats stats; + getRTSStats(&stats); + Time mut_time = stats.mutator_cpu_ns; + StgDouble seconds = TimeToSecondsDbl(mut_time); printSample(true, seconds); printSample(false, seconds); fclose(hp_file); ===================================== testsuite/tests/ghci/should_fail/T18052b.script ===================================== @@ -0,0 +1,2 @@ +:set -XMagicHash +let (%%%) = 1# ===================================== testsuite/tests/ghci/should_fail/T18052b.stderr ===================================== @@ -0,0 +1,3 @@ + +:1:1: error: + GHCi can't bind a variable of unlifted type: (%%%) :: GHC.Prim.Int# ===================================== testsuite/tests/ghci/should_fail/all.T ===================================== @@ -3,3 +3,4 @@ test('T10549a', [], ghci_script, ['T10549a.script']) test('T15055', normalise_version('ghc'), ghci_script, ['T15055.script']) test('T16013', [], ghci_script, ['T16013.script']) test('T16287', [], ghci_script, ['T16287.script']) +test('T18052b', [], ghci_script, ['T18052b.script']) ===================================== testsuite/tests/partial-sigs/should_compile/ExtraConstraints3.stderr ===================================== @@ -1,28 +1,28 @@ TYPE SIGNATURES - !! :: forall {a}. [a] -> Int -> a - $ :: forall {a} {b}. (a -> b) -> a -> b - $! :: forall {a} {b}. (a -> b) -> a -> b - && :: Bool -> Bool -> Bool - * :: forall {a}. Num a => a -> a -> a - ** :: forall {a}. Floating a => a -> a -> a - + :: forall {a}. Num a => a -> a -> a - ++ :: forall {a}. [a] -> [a] -> [a] - - :: forall {a}. Num a => a -> a -> a - . :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c - / :: forall {a}. Fractional a => a -> a -> a - /= :: forall {a}. Eq a => a -> a -> Bool - < :: forall {a}. Ord a => a -> a -> Bool - <= :: forall {a}. Ord a => a -> a -> Bool - =<< :: + (!!) :: forall {a}. [a] -> Int -> a + ($) :: forall {a} {b}. (a -> b) -> a -> b + ($!) :: forall {a} {b}. (a -> b) -> a -> b + (&&) :: Bool -> Bool -> Bool + (*) :: forall {a}. Num a => a -> a -> a + (**) :: forall {a}. Floating a => a -> a -> a + (+) :: forall {a}. Num a => a -> a -> a + (++) :: forall {a}. [a] -> [a] -> [a] + (-) :: forall {a}. Num a => a -> a -> a + (.) :: forall {b} {c} {a}. (b -> c) -> (a -> b) -> a -> c + (/) :: forall {a}. Fractional a => a -> a -> a + (/=) :: forall {a}. Eq a => a -> a -> Bool + (<) :: forall {a}. Ord a => a -> a -> Bool + (<=) :: forall {a}. Ord a => a -> a -> Bool + (=<<) :: forall {m :: * -> *} {a} {b}. Monad m => (a -> m b) -> m a -> m b - == :: forall {a}. Eq a => a -> a -> Bool - > :: forall {a}. Ord a => a -> a -> Bool - >= :: forall {a}. Ord a => a -> a -> Bool - >> :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b - >>= :: + (==) :: forall {a}. Eq a => a -> a -> Bool + (>) :: forall {a}. Ord a => a -> a -> Bool + (>=) :: forall {a}. Ord a => a -> a -> Bool + (>>) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> m b -> m b + (>>=) :: forall {m :: * -> *} {a} {b}. Monad m => m a -> (a -> m b) -> m b - ^ :: forall {b} {a}. (Integral b, Num a) => a -> b -> a - ^^ :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a + (^) :: forall {b} {a}. (Integral b, Num a) => a -> b -> a + (^^) :: forall {a} {b}. (Fractional a, Integral b) => a -> b -> a abs :: forall {a}. Num a => a -> a acos :: forall {a}. Floating a => a -> a acosh :: forall {a}. Floating a => a -> a @@ -234,7 +234,7 @@ TYPE SIGNATURES zipWith3 :: forall {a} {b} {c} {d}. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] - || :: Bool -> Bool -> Bool + (||) :: Bool -> Bool -> Bool Dependent modules: [] -Dependent packages: [base-4.13.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/partial-sigs/should_compile/T18008.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE PartialTypeSignatures #-} +module Bug where + +f :: (forall a. Show a => a -> String) -> _ +f s = s () + ===================================== testsuite/tests/partial-sigs/should_compile/T18008.stderr ===================================== @@ -0,0 +1,5 @@ + +T18008.hs:5:43: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_’ standing for ‘String’ + • In the type ‘(forall a. Show a => a -> String) -> _’ + In the type signature: f :: (forall a. Show a => a -> String) -> _ ===================================== testsuite/tests/partial-sigs/should_compile/all.T ===================================== @@ -95,3 +95,4 @@ test('T16334', normal, compile, ['']) test('T16728', normal, compile, ['']) test('T16728a', normal, compile, ['']) test('T16728b', normal, compile, ['']) +test('T18008', normal, compile, ['']) ===================================== testsuite/tests/printer/T18052a.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeOperators #-} +module T18052a where + +(+++) = (++) +pattern x :||: y = (x,y) +type (^^^) = Either +data (&&&) ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -0,0 +1,42 @@ +TYPE SIGNATURES + (+++) :: forall {a}. [a] -> [a] -> [a] +TYPE CONSTRUCTORS + data type (&&&){0} :: * + type synonym (^^^){0} :: * -> * -> * +PATTERN SYNONYMS + (:||:) :: forall {a} {b}. a -> b -> (a, b) +Dependent modules: [] +Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 18, types: 53, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) +[GblId, Arity=2, Unf=OtherCon []] +T18052a.$b:||: = GHC.Tuple.(,) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +(+++) :: forall {a}. [a] -> [a] -> [a] +[GblId] +(+++) = (++) + +-- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +T18052a.$m:||: + :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. + (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r +[GblId, Arity=3, Unf=OtherCon []] +T18052a.$m:||: + = \ (@(rep :: GHC.Types.RuntimeRep)) + (@(r :: TYPE rep)) + (@a) + (@b) + (scrut :: (a, b)) + (cont :: a -> b -> r) + _ [Occ=Dead] -> + case scrut of { (x, y) -> cont x y } + + + ===================================== testsuite/tests/printer/all.T ===================================== @@ -57,3 +57,5 @@ test('T14306', ignore_stderr, makefile_test, ['T14306']) test('T14343', normal, compile_fail, ['']) test('T14343b', normal, compile_fail, ['']) test('T15761', normal, compile_fail, ['']) +test('T18052a', normal, compile, + ['-ddump-simpl -ddump-types -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/76501b74ef73151c11766cd710283ada34205afb...658bda511237593bb80389280d0364180648058d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/76501b74ef73151c11766cd710283ada34205afb...658bda511237593bb80389280d0364180648058d You're receiving 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 17 15:56:40 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 17 Apr 2020 11:56:40 -0400 Subject: [Git][ghc/ghc][wip/T17173] Do eager instantation in terms Message-ID: <5e99d1b86f32f_61673f81ef22dee4543129@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: e1fb3157 by Simon Peyton Jones at 2020-04-17T16:55:46+01:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 30 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Instantiate.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Zonk.hs - libraries/base/tests/T9681.stderr - testsuite/tests/ado/T13242a.stderr - testsuite/tests/ado/ado002.stderr - testsuite/tests/annotations/should_fail/annfail08.stderr - testsuite/tests/driver/T2182.stderr - testsuite/tests/gadt/gadt13.stderr - testsuite/tests/ghci/scripts/Defer02.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1fb31571f4eb16ea6fe2803a088d15bcbc5f0c4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1fb31571f4eb16ea6fe2803a088d15bcbc5f0c4 You're receiving 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 17 16:00:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 17 Apr 2020 12:00:05 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Lint changes Message-ID: <5e99d2856ac46_61673f81ef22dee4543373f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 74af4ca8 by Ben Gamari at 2020-04-17T15:02:17+00:00 Lint changes - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -702,6 +702,8 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go binders0 go _ = markAllJoinsBad $ lintCoreExpr rhs +-- | Lint the RHS of a join point with expected join arity of @n@ (see Note +-- [Join points] in GHC.Core). lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM LintedType lintJoinLams join_arity enforce rhs = go join_arity rhs @@ -864,14 +866,9 @@ lintCoreExpr e@(App _ _) | Var fun <- fun , fun `hasKey` keepAliveIdKey , [arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5, arg6, arg7] <- args - = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 -- ra :: RuntimeRep - ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 -- a :: TYPE ra - ; fun_ty3 <- lintCoreArg fun_ty2 arg_ty3 -- ro :: RuntimeRep - ; fun_ty4 <- lintCoreArg fun_ty3 arg_ty4 -- o :: TYPE ro - ; fun_ty5 <- lintCoreArg fun_ty4 arg5 -- x :: a - ; arg_ty6 <- lintJoinLams 1 (Just fun) arg6 -- f :: State# RW -> (# State# RW, o #) - ; fun_ty6 <- lintValApp arg6 fun_ty5 arg_ty6 - ; lintCoreArg fun_ty6 arg7 -- s0 :: State# RW + = do { fun_ty5 <- lintCoreArgs (idType fun) [ arg_ty1, arg_ty2, arg_ty3, arg_ty4 ] + ; arg6_ty <- lintJoinLams 1 (Just fun) arg6 -- f :: State# RW -> (# State# RW, o #) + ; lintCoreArgs fun_ty5 [arg5, arg6, arg7] } | otherwise @@ -1135,6 +1132,10 @@ lintTyApp fun_ty arg_ty = failWithL (mkTyAppMsg fun_ty arg_ty) ----------------- + +-- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@ +-- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the +-- application. lintValApp :: CoreExpr -> LintedType -> LintedType -> LintM LintedType lintValApp arg fun_ty arg_ty | Just (arg_ty', res_ty') <- splitFunTy_maybe fun_ty View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74af4ca81c37b72429536a3a81fe6b42b6e17a1f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74af4ca81c37b72429536a3a81fe6b42b6e17a1f You're receiving 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 17 16:14:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 17 Apr 2020 12:14:03 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] Fix warning Message-ID: <5e99d5cbde8a2_616776d1c74544028e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 75093e21 by Ben Gamari at 2020-04-17T16:11:36+00:00 Fix warning - - - - - 1 changed file: - compiler/GHC/StgToCmm/Closure.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -626,7 +626,7 @@ getCallMethod _ _name _ LFLetNoEscape _n_args _v_args (LneLoc blk_id lne_regs) _self_loop_info = JumpToIt blk_id lne_regs -getCallMethod _ name _ lf_info _ _ _ _ = pprPanic "Unknown call method" (ppr name) +getCallMethod _ name _ _lf_info _ _ _ _ = pprPanic "Unknown call method" (ppr name) ----------------------------------------------------------------------------- -- Data types for closure information View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75093e219f059a57ee4358eb3e787ff87d7fec13 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75093e219f059a57ee4358eb3e787ff87d7fec13 You're receiving 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 17 16:20:57 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Fri, 17 Apr 2020 12:20:57 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e99d769cc2d1_61673f8199536d945444354@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: a9ae9d5e by John Ericson at 2020-04-17T12:20:36-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -23,8 +23,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +62,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +73,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +173,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +244,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +277,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +304,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +326,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +526,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +562,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +577,37 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +646,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +731,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +747,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +764,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +785,14 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +834,23 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +862,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +874,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +903,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a9ae9d5ec09a33befd33711f6c0a3695d41bf62c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a9ae9d5ec09a33befd33711f6c0a3695d41bf62c You're receiving 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 17 16:33:51 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 17 Apr 2020 12:33:51 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Fix "build/elem" RULE. Message-ID: <5e99da6f45ad8_61673f8199536d94545697e@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 4ff4fb4f by Andreas Klebinger at 2020-04-17T18:30:23+02:00 Fix "build/elem" RULE. An redundant constraint prevented the rule from matching. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. Surprisingly this seems to regress elem for strings. To avoid this we now also allow foldrCString to inline and add an UTF8 variant. This results in elem being compiled to a tight non-allocating loop over the primitive string literal which performs a linear search. In the process this commit adds UTF8 variants for some of the functions in CString. This is required to make this work for both ASCII and UTF8 strings. There is also a small tweak to the AppendLitString rule. We allow ourselfes the luxury to compare the folding function via eqExpr, which helps to ensure the rule fires before we inline foldrCString*. - - - - - 10 changed files: - compiler/GHC/Core/Op/ConstantFold.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -43,10 +43,13 @@ import GHC.Core.TyCon , isNewTyCon, unwrapNewTyCon_maybe, tyConDataCons , tyConFamilySize ) import GHC.Core.DataCon ( dataConTagZ, dataConTyCon, dataConWrapId, dataConWorkId ) -import GHC.Core.Utils ( cheapEqExpr, cheapEqExpr', exprIsHNF, exprType +import GHC.Core.Utils ( eqExpr, cheapEqExpr, exprIsHNF, exprType , stripTicksTop, stripTicksTopT, mkTicks ) import GHC.Core.Unfold ( exprIsConApp_maybe ) +import GHC.Core.FVs import GHC.Core.Type +import GHC.Types.Var.Set +import GHC.Types.Var.Env import GHC.Types.Name.Occurrence ( occNameFS ) import PrelNames import Maybes ( orElse ) @@ -1254,7 +1257,7 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, @@ -1430,11 +1433,16 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo" c (unpackFoldrCString*# "baz" c n) +-- = unpackFoldrCString*# "foobaz" c n -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey + +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,12 +1455,13 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey - , cheapEqExpr' tickishFloatable c1 c2 - , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 - , c2Ticks <- stripTicksTopT tickishFloatable c2 + , unpk `hasKey` foldVariant , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 + , let freeVars = (mkInScopeSet (exprFreeVars c1 `unionVarSet` exprFreeVars c2)) + in eqExpr freeVars c1 c2 + , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 + , c2Ticks <- stripTicksTopT tickishFloatable c2 = ASSERT( ty1 `eqType` ty2 ) Just $ mkTicks strTicks $ Var unpk `App` Type ty1 @@ -1460,7 +1469,7 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1624,6 +1624,10 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n +"unpack-utf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-list-utf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-append-utf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + -- There's a built-in rule (in GHC.Core.Op.ConstantFold) for -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,7 +1149,7 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} #endif @@ -1174,7 +1174,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -11,7 +11,9 @@ * Add `singleton` function for `Data.List.NonEmpty`. - + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement more often. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,15 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques -dsuppress-all + # All occurences of elem should be optimized away. + # For strings these should result in loops after inlining foldCString. + # For lists it should result in a case expression. + echo $$(cat T17752.dump-simpl | grep "elem" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,18 @@ +module T17752 where + +-- All occurences of elem should be optimized away. +-- For strings these should result in loops after inlining foldCString. +-- For lists it should result in a case expression. + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +isOneOfThese x = x `elem` [1,2,3,4,5::Int] +isNotOneOfThese x = x `notElem` [1,2,3,4,5::Int] + +isElemString x = elem x "foo" +isNotElemString x = notElem x "bar" + +isElemStringUtf x = elem x "foö" +isNotElemStringUtf x = notElem x "bär" ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,2 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) + ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,13 +17,77 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types import GHC.Prim +{- +Note [String literals in GHC] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +String literals get quite a bit of special handling in GHC. This Note +summarises the moving parts. + +* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in + turn calls GHC.Core.Make.mkStringExprFS. + + The desugarer desugars the Haskell literal "foo" into Core + GHC.CString.unpackCString# "foo"# + where "foo"# is primitive string literal (of type Addr#). + + When the string cannot be encoded as a C string, we use UTF8: + GHC.CString.unpackCStringUtf8# "foo"# + +* The library module ghc-prim:GHC.CString has a bunch of functions that + work over primitive strings, including GHC.CString.unpackCString# + +* GHC.Core.Op.ConstantFold has some RULES that optimise certain string + operations on literal strings. For example: + + + Constant folding the desugared form of ("foo" ++ "bar") + into ("foobar") + + Comparing strings + + and more + +* GHC.Base has a number of regular rules for String literals. + + + a rule "eqString": (==) @String = eqString + where GHC.Base.eqString :: String -> String -> Bool + + ConstantFold has a RULE for eqString on literals: + eqString (Lit "foo"#) (Lit "bar"#) --> False + + This allows compile time evaluation of things like "foo" == "bar" + + + A bunch of rules to promote fusion: + + "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) + "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a + "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n + + And UTF8 variants of these rules. + +* We allow primitive (unlifted) literal strings to be top-level + bindings, breaking out usual rule. See GHC.Core + Note [Core top-level string literals] + +* TODO: There is work on a special code-gen path for top-level boxed strings + str :: [Char] + str = unpackCString# "foo"# + so that they can all share a common code pointer + + There is a WIP MR on gitlab for this: !3012 + +-} + ----------------------------------------------------------------------------- -- Unpacking C strings ----------------------------------------------------------------------------- @@ -71,8 +135,27 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Inlining of unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n + +We use NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. + +This can cause a code size increase but it was minimal +when looking at nofib. + +This is especially important for elem which then results in an +allocation free loop. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +172,10 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +198,17 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- See [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +216,43 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +271,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explicit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,15 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + +- unpackFoldrCString* variants can now inline in phase [0]. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ff4fb4fc8081a266c84d88219a5196c17fbf92c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ff4fb4fc8081a266c84d88219a5196c17fbf92c You're receiving 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 17 16:45:35 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 17 Apr 2020 12:45:35 -0400 Subject: [Git][ghc/ghc][master] Hadrian: fix dyn_o/dyn_hi rule (#17534) Message-ID: <5e99dd2f9b342_61673f81ef22dee454637bc@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - 1 changed file: - hadrian/src/Rules/Compile.hs Changes: ===================================== hadrian/src/Rules/Compile.hs ===================================== @@ -55,7 +55,22 @@ compilePackage rs = do &%> \ [dyn_o, _dyn_hi] -> do p <- platformSupportsSharedLibs if p - then need [dyn_o -<.> "o", dyn_o -<.> "hi"] + then do + -- We `need` ".o/.hi" because GHC is called with `-dynamic-too` + -- and builds ".dyn_o/.dyn_hi" too. + changed <- needHasChanged [dyn_o -<.> "o", dyn_o -<.> "hi"] + + -- If for some reason a previous Hadrian execution has been + -- interrupted after the rule for .o/.hi generation has completed + -- but before the current rule for .dyn_o/.dyn_hi has completed, + -- or if some of the dynamic artifacts have been removed by the + -- user, "needing" the non dynamic artifacts is not enough as + -- Shake won't execute the associated action. Hence we detect + -- this case and we explictly build the dynamic artifacts here: + case changed of + [] -> compileHsObjectAndHi rs dyn_o + _ -> pure () + else compileHsObjectAndHi rs dyn_o forM_ ((,) <$> hsExts <*> wayPats) $ \ ((oExt, hiExt), wayPat) -> View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85fc32f03a6df92ec8d4ec9accca3c11b31a1596 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85fc32f03a6df92ec8d4ec9accca3c11b31a1596 You're receiving 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 17 16:45:43 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 17 Apr 2020 12:45:43 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Fix "build/elem" RULE. Message-ID: <5e99dd379d51d_61673f8199536d945463988@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: a5b03183 by Andreas Klebinger at 2020-04-17T18:43:57+02:00 Fix "build/elem" RULE. An redundant constraint prevented the rule from matching. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. Surprisingly this seems to regress elem for strings. To avoid this we now also allow foldrCString to inline and add an UTF8 variant. This results in elem being compiled to a tight non-allocating loop over the primitive string literal which performs a linear search. In the process this commit adds UTF8 variants for some of the functions in GHC.CString. This is required to make this work for both ASCII and UTF8 strings. There are also small tweaks to the CString related rules. We now allow ourselfes the luxury to compare the folding function via eqExpr, which helps to ensure the rule fires before we inline foldrCString*. Together with a few changes to allow matching on both the UTF8 and ASCII variants of the CString functions. - - - - - 11 changed files: - compiler/GHC/Core/Op/ConstantFold.hs - compiler/prelude/PrelNames.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -43,10 +43,13 @@ import GHC.Core.TyCon , isNewTyCon, unwrapNewTyCon_maybe, tyConDataCons , tyConFamilySize ) import GHC.Core.DataCon ( dataConTagZ, dataConTyCon, dataConWrapId, dataConWorkId ) -import GHC.Core.Utils ( cheapEqExpr, cheapEqExpr', exprIsHNF, exprType +import GHC.Core.Utils ( eqExpr, cheapEqExpr, exprIsHNF, exprType , stripTicksTop, stripTicksTopT, mkTicks ) import GHC.Core.Unfold ( exprIsConApp_maybe ) +import GHC.Core.FVs import GHC.Core.Type +import GHC.Types.Var.Set +import GHC.Types.Var.Env import GHC.Types.Name.Occurrence ( occNameFS ) import PrelNames import Maybes ( orElse ) @@ -1254,7 +1257,10 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, + BuiltinRule { ru_name = fsLit "AppendLitStringUtf8", + ru_fn = unpackCStringFoldrUtf8Name, + ru_nargs = 4, ru_try = match_append_lit_utf8 }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, @@ -1430,11 +1436,20 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo" c (unpackFoldrCString*# "baz" c n) +-- = unpackFoldrCString*# "foobaz" c n -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey + +-- CStringUTF8 version +match_append_lit_utf8 :: RuleFun +match_append_lit_utf8 = match_append_lit unpackCStringFoldrUtf8IdKey + +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,12 +1462,13 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey - , cheapEqExpr' tickishFloatable c1 c2 - , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 - , c2Ticks <- stripTicksTopT tickishFloatable c2 + , unpk `hasKey` foldVariant , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 + , let freeVars = (mkInScopeSet (exprFreeVars c1 `unionVarSet` exprFreeVars c2)) + in eqExpr freeVars c1 c2 + , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 + , c2Ticks <- stripTicksTopT tickishFloatable c2 = ASSERT( ty1 `eqType` ty2 ) Just $ mkTicks strTicks $ Var unpk `App` Type ty1 @@ -1460,24 +1476,29 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)) = s1==s2 +-- Also matches unpackCStringUtf8# match_eq_string :: RuleFun match_eq_string _ id_unf _ [Var unpk1 `App` lit1, Var unpk2 `App` lit2] - | unpk1 `hasKey` unpackCStringIdKey - , unpk2 `hasKey` unpackCStringIdKey + | unpk_key1 <- getUnique unpk1 + , unpk_key2 <- getUnique unpk2 + , unpk_key1 == unpk_key2 + -- For now we insist the literals have to agree in their encoding + -- to keep the rule simple. But we could check if the decoded strings + -- compare equal in here as well. + , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 = Just (if s1 == s2 then trueValBool else falseValBool) match_eq_string _ _ _ _ = Nothing - --------------------------------------------------- -- The rule is this: -- inline f_ty (f a b c) = a b c ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -340,8 +340,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, -- Overloaded lists isListClassName, @@ -712,11 +712,12 @@ ioDataCon_RDR :: RdrName ioDataCon_RDR = nameRdrName ioDataConName eqString_RDR, unpackCString_RDR, unpackCStringFoldr_RDR, - unpackCStringUtf8_RDR :: RdrName + unpackCStringFoldrUtf8_RDR, unpackCStringUtf8_RDR :: RdrName eqString_RDR = nameRdrName eqStringName unpackCString_RDR = nameRdrName unpackCStringName unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name +unpackCStringFoldrUtf8_RDR = nameRdrName unpackCStringFoldrUtf8Name newStablePtr_RDR :: RdrName newStablePtr_RDR = nameRdrName newStablePtrName @@ -1006,11 +1007,12 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name,eqStringName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -2087,7 +2089,8 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey :: Unique @@ -2111,11 +2114,12 @@ recConErrorIdKey = mkPreludeMiscIdUnique 16 unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 17 unpackCStringAppendIdKey = mkPreludeMiscIdUnique 18 unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 19 -unpackCStringIdKey = mkPreludeMiscIdUnique 20 -voidPrimIdKey = mkPreludeMiscIdUnique 21 -typeErrorIdKey = mkPreludeMiscIdUnique 22 -divIntIdKey = mkPreludeMiscIdUnique 23 -modIntIdKey = mkPreludeMiscIdUnique 24 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 20 +unpackCStringIdKey = mkPreludeMiscIdUnique 21 +voidPrimIdKey = mkPreludeMiscIdUnique 22 +typeErrorIdKey = mkPreludeMiscIdUnique 23 +divIntIdKey = mkPreludeMiscIdUnique 24 +modIntIdKey = mkPreludeMiscIdUnique 25 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1624,6 +1624,10 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n +"unpack-utf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-list-utf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-append-utf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + -- There's a built-in rule (in GHC.Core.Op.ConstantFold) for -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,7 +1149,7 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} #endif @@ -1174,7 +1174,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -11,7 +11,13 @@ * Add `singleton` function for `Data.List.NonEmpty`. + * Add rules `unpackUtf8`, `unpack-listUtf8` and `unpack-appendUtf8` to `GHC.Base`. + They correspond to their ascii versions and hopefully make it easier + for libraries to handle utf8 encoded strings efficiently. + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement more often. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,15 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques -dsuppress-all + # All occurences of elem should be optimized away. + # For strings these should result in loops after inlining foldCString. + # For lists it should result in a case expression. + echo $$(cat T17752.dump-simpl | grep "elem" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,18 @@ +module T17752 where + +-- All occurences of elem should be optimized away. +-- For strings these should result in loops after inlining foldCString. +-- For lists it should result in a case expression. + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +isOneOfThese x = x `elem` [1,2,3,4,5::Int] +isNotOneOfThese x = x `notElem` [1,2,3,4,5::Int] + +isElemString x = elem x "foo" +isNotElemString x = notElem x "bar" + +isElemStringUtf x = elem x "foö" +isNotElemStringUtf x = notElem x "bär" ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,2 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) + ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,13 +17,77 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types import GHC.Prim +{- +Note [String literals in GHC] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +String literals get quite a bit of special handling in GHC. This Note +summarises the moving parts. + +* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in + turn calls GHC.Core.Make.mkStringExprFS. + + The desugarer desugars the Haskell literal "foo" into Core + GHC.CString.unpackCString# "foo"# + where "foo"# is primitive string literal (of type Addr#). + + When the string cannot be encoded as a C string, we use UTF8: + GHC.CString.unpackCStringUtf8# "foo"# + +* The library module ghc-prim:GHC.CString has a bunch of functions that + work over primitive strings, including GHC.CString.unpackCString# + +* GHC.Core.Op.ConstantFold has some RULES that optimise certain string + operations on literal strings. For example: + + + Constant folding the desugared form of ("foo" ++ "bar") + into ("foobar") + + Comparing strings + + and more + +* GHC.Base has a number of regular rules for String literals. + + + a rule "eqString": (==) @String = eqString + where GHC.Base.eqString :: String -> String -> Bool + + ConstantFold has a RULE for eqString on literals: + eqString (Lit "foo"#) (Lit "bar"#) --> False + + This allows compile time evaluation of things like "foo" == "bar" + + + A bunch of rules to promote fusion: + + "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) + "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a + "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n + + And UTF8 variants of these rules. + +* We allow primitive (unlifted) literal strings to be top-level + bindings, breaking out usual rule. See GHC.Core + Note [Core top-level string literals] + +* TODO: There is work on a special code-gen path for top-level boxed strings + str :: [Char] + str = unpackCString# "foo"# + so that they can all share a common code pointer + + There is a WIP MR on gitlab for this: !3012 + +-} + ----------------------------------------------------------------------------- -- Unpacking C strings ----------------------------------------------------------------------------- @@ -71,8 +135,27 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Inlining of unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n + +We use NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. + +This can cause a code size increase but it was minimal +when looking at nofib. + +This is especially important for elem which then results in an +allocation free loop. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +172,10 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +198,17 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- See [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +216,43 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +271,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explicit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,15 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + +- unpackFoldrCString* variants can now inline in phase [0]. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5b03183e9d177469678a52388d06181fbb30cac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5b03183e9d177469678a52388d06181fbb30cac You're receiving 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 17 16:46:13 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 17 Apr 2020 12:46:13 -0400 Subject: [Git][ghc/ghc][master] Fix #18065 by fixing an InstCo oversight in Core Lint Message-ID: <5e99dd55cfe88_616713503ee0546856c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - 3 changed files: - compiler/GHC/Core/Lint.hs - + testsuite/tests/indexed-types/should_compile/T18065.hs - testsuite/tests/indexed-types/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2030,21 +2030,21 @@ lintCoercion the_co@(LRCo lr co) lintCoercion (InstCo co arg) = do { co' <- lintCoercion co ; arg' <- lintCoercion arg - ; let Pair t1' t2' = coercionKind co' - Pair s1 s2 = coercionKind arg + ; let Pair t1 t2 = coercionKind co' + Pair s1 s2 = coercionKind arg' ; lintRole arg Nominal (coercionRole arg') - ; case (splitForAllTy_ty_maybe t1', splitForAllTy_ty_maybe t2') of + ; case (splitForAllTy_ty_maybe t1, splitForAllTy_ty_maybe t2) of -- forall over tvar { (Just (tv1,_), Just (tv2,_)) | typeKind s1 `eqType` tyVarKind tv1 , typeKind s2 `eqType` tyVarKind tv2 -> return (InstCo co' arg') | otherwise - -> failWithL (text "Kind mis-match in inst coercion") + -> failWithL (text "Kind mis-match in inst coercion1" <+> ppr co) - ; _ -> case (splitForAllTy_co_maybe t1', splitForAllTy_co_maybe t2') of + ; _ -> case (splitForAllTy_co_maybe t1, splitForAllTy_co_maybe t2) of -- forall over covar { (Just (cv1, _), Just (cv2, _)) | typeKind s1 `eqType` varType cv1 @@ -2053,7 +2053,7 @@ lintCoercion (InstCo co arg) , CoercionTy _ <- s2 -> return (InstCo co' arg') | otherwise - -> failWithL (text "Kind mis-match in inst coercion") + -> failWithL (text "Kind mis-match in inst coercion2" <+> ppr co) ; _ -> failWithL (text "Bad argument of inst") }}} ===================================== testsuite/tests/indexed-types/should_compile/T18065.hs ===================================== @@ -0,0 +1,108 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +module T18065 where + +import Data.Kind +import Data.List.NonEmpty (NonEmpty(..)) + +type family Sing :: k -> Type +data TyFun :: Type -> Type -> Type +type a ~> b = TyFun a b -> Type +infixr 0 ~> +type family Apply (f :: a ~> b) (x :: a) :: b + +type SingFunction1 f = forall t. Sing t -> Sing (f `Apply` t) +singFun1 :: forall f. SingFunction1 f -> Sing f +singFun1 f = SLambda f + +type SingFunction2 f = forall t1 t2. Sing t1 -> Sing t2 -> Sing (f `Apply` t1 `Apply` t2) +singFun2 :: forall f. SingFunction2 f -> Sing f +singFun2 f = SLambda (\x -> singFun1 (f x)) + +newtype SLambda (f :: a ~> b) = + SLambda { applySing :: forall t. Sing t -> Sing (f `Apply` t) } +type instance Sing = SLambda + +data SList :: forall a. [a] -> Type where + SNil :: SList '[] + SCons :: Sing x -> Sing xs -> SList (x:xs) +type instance Sing = SList + +data SNonEmpty :: forall a. NonEmpty a -> Type where + (:%|) :: Sing x -> Sing xs -> SNonEmpty (x:|xs) +type instance Sing = SNonEmpty + +type family Id (x :: a) :: a where + Id x = x +data IdSym0 :: a ~> a +type instance Apply IdSym0 x = Id x +sId :: forall a (x :: a). Sing x -> Sing (Id x) +sId sx = sx + +type family (.) (f :: b ~> c) (g :: a ~> b) (x :: a) :: c where + (f . g) x = f `Apply` (g `Apply` x) +data (.@#@$) :: (b ~> c) ~> (a ~> b) ~> a ~> c +data (.@#@$$) :: (b ~> c) -> (a ~> b) ~> a ~> c +data (.@#@$$$) :: (b ~> c) -> (a ~> b) -> a ~> c +type instance Apply (.@#@$) f = (.@#@$$) f +type instance Apply ((.@#@$$) f) g = (.@#@$$$) f g +type instance Apply ((.@#@$$$) f g) x = (f . g) x +(%.) :: forall b c a (f :: b ~> c) (g :: a ~> b) (x :: a). + Sing f -> Sing g -> Sing x -> Sing ((f . g) x) +(%.) sf sg sx = sf `applySing` (sg `applySing` sx) + +type family Go (k :: a ~> b ~> b) (z :: b) (l :: [a]) :: b where + Go _ z '[] = z + Go k z (y:ys) = k `Apply` y `Apply` Go k z ys +data GoSym :: (a ~> b ~> b) -> b -> [a] ~> b +type instance Apply (GoSym k z) l = Go k z l +type family Listfoldr (k :: a ~> b ~> b) (z :: b) (l :: [a]) :: b where + Listfoldr k z l = Go k z l +sListfoldr :: forall a b (k :: a ~> b ~> b) (z :: b) (l :: [a]). + Sing k -> Sing z -> Sing l -> Sing (Listfoldr k z l) +sListfoldr sk sz = sGo + where + sGo :: forall l'. Sing l' -> Sing (GoSym k z `Apply` l') + sGo SNil = sz + sGo (sy `SCons` sys) = sk `applySing` sy `applySing` sGo sys + +class PMonoid a where + type Mempty :: a + type Mappend (x :: a) (y :: a) :: a +data MappendSym0 :: a ~> a ~> a +data MappendSym1 :: a -> a ~> a +type instance Apply MappendSym0 x = MappendSym1 x +type instance Apply (MappendSym1 x) y = Mappend x y +class SMonoid a where + sMempty :: Sing (Mempty :: a) + sMappend :: forall (x :: a) (y :: a). Sing x -> Sing y -> Sing (Mappend x y) + +class PFoldable t where + type Foldr (f :: a ~> b ~> b) (z :: b) (l :: t a) :: b +instance PFoldable [] where + type Foldr f z l = Listfoldr f z l +class SFoldable t where + sFoldr :: forall a b (f :: a ~> b ~> b) (z :: b) (l :: t a). + Sing f -> Sing z -> Sing l -> Sing (Foldr f z l) +instance SFoldable [] where + sFoldr = sListfoldr + +type family FoldMap (f :: a ~> m) (l :: t a) :: m where + FoldMap f l = Foldr (MappendSym0 .@#@$$$ f) Mempty l +sFoldMap :: forall t a m (f :: a ~> m) (l :: t a). + (SFoldable t, SMonoid m) + => Sing f -> Sing l -> Sing (FoldMap f l) +sFoldMap sf = sFoldr (singFun2 @((.@#@$$) MappendSym0) (singFun2 @MappendSym0 sMappend %.) `applySing` sf) sMempty + +type family NEFold (l :: NonEmpty m) :: m where + NEFold (a :| as) = a `Mappend` FoldMap IdSym0 as +sNEFold :: forall m (l :: NonEmpty m). SMonoid m + => Sing l -> Sing (NEFold l) +sNEFold (sa :%| sas) = sa `sMappend` sFoldMap (singFun1 @IdSym0 sId) sas ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -295,3 +295,4 @@ test('T17008b', normal, compile, ['']) test('T17056', normal, compile, ['']) test('T17405', normal, multimod_compile, ['T17405c', '-v0']) test('T17923', normal, compile, ['']) +test('T18065', normal, compile, ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bfde3b76ac7f5a72eca012fe34ac1340a5ce2011 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bfde3b76ac7f5a72eca012fe34ac1340a5ce2011 You're receiving 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 17 17:02:06 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Fri, 17 Apr 2020 13:02:06 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e99e10edb3d8_616776d1c7454789a7@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 475bfffe by John Ericson at 2020-04-17T13:01:39-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -10,6 +10,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] @@ -23,8 +24,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +63,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +74,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +174,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +245,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +278,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +305,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +327,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +527,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +563,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +578,37 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +647,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +732,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +748,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +765,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +786,14 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +835,23 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +863,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +875,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +904,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/475bfffeccbd42feeed2628a405d0f968440856c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/475bfffeccbd42feeed2628a405d0f968440856c You're receiving 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 17 17:02:39 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Fri, 17 Apr 2020 13:02:39 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 3 commits: Hadrian: fix dyn_o/dyn_hi rule (#17534) Message-ID: <5e99e12f6275e_6167134ebbc45479951@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - c7c6c6cb by John Ericson at 2020-04-17T13:02:37-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 30 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - hadrian/src/Rules/Compile.hs - testsuite/tests/ghc-api/T6145.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/475bfffeccbd42feeed2628a405d0f968440856c...c7c6c6cb0ea011dbd26c172ec96348d6f6f1bf90 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/475bfffeccbd42feeed2628a405d0f968440856c...c7c6c6cb0ea011dbd26c172ec96348d6f6f1bf90 You're receiving 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 17 17:18:04 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 17 Apr 2020 13:18:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 13 commits: Hadrian: fix dyn_o/dyn_hi rule (#17534) Message-ID: <5e99e4cc4c0b7_616776d1c74548494c@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - 5d8963e9 by Sylvain Henry at 2020-04-17T13:17:43-04:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 6728f1de by Sylvain Henry at 2020-04-17T13:17:43-04:00 Modules: SysTools (#13009) - - - - - 04a565ee by Sylvain Henry at 2020-04-17T13:17:43-04:00 Modules: Parser (#13009) - - - - - d71b7dd9 by Sylvain Henry at 2020-04-17T13:17:43-04:00 Modules: GHC.Builtin (#13009) - - - - - 12db883f by Sylvain Henry at 2020-04-17T13:17:43-04:00 Modules: GHC.Iface.Recomp (#13009) - - - - - 953f3ddc by Sylvain Henry at 2020-04-17T13:17:43-04:00 Modules: Settings (#13009) Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - 7bac731b by Ben Gamari at 2020-04-17T13:17:44-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 49cb3f88 by Ben Gamari at 2020-04-17T13:17:44-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - d8eb6e86 by Ben Gamari at 2020-04-17T13:17:44-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 2effbff2 by Ben Gamari at 2020-04-17T13:17:44-04:00 Bump hsc2hs submodule - - - - - bcb221d9 by Ömer Sinan Ağacan at 2020-04-17T13:17:57-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eefc926c0871224d2679e8eb6534c5335a3409d6...bcb221d97a57d5b637e8e1ab9ea56b27c5800667 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eefc926c0871224d2679e8eb6534c5335a3409d6...bcb221d97a57d5b637e8e1ab9ea56b27c5800667 You're receiving 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 17 17:51:35 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Fri, 17 Apr 2020 13:51:35 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e99eca77e86_6167134ebbc454926d5@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 78a403cc by John Ericson at 2020-04-17T13:51:11-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -10,6 +10,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] @@ -23,8 +24,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +63,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +74,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +174,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +245,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +278,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +305,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +327,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +527,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +563,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +578,37 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +647,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +732,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +748,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +765,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +786,14 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +835,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +861,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +873,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +902,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,13 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of + GhcPs -> noExtCon e + GhcRn -> noExtCon e + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/78a403cca979c395e6187df02a415f890af0a0be -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/78a403cca979c395e6187df02a415f890af0a0be You're receiving 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 17 19:21:36 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Fri, 17 Apr 2020 15:21:36 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e9a01c0d40c6_6167e4e49b455011ae@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: 35a4fdb9 by John Ericson at 2020-04-17T15:21:15-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - compiler/parser/RdrHsSyn.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -355,6 +355,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -10,6 +10,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] @@ -23,8 +24,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +63,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import TysWiredIn import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +74,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +174,12 @@ data Pat p -- For details on above see note [Api annotations] in ApiAnnotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +245,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +278,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +305,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +327,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +527,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +563,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +578,37 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +647,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +732,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +748,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +765,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +786,14 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +835,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +861,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +873,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +902,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -88,6 +91,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -134,6 +138,7 @@ import Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,15 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon e + GhcRn -> noExtCon e +#endif + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1821,13 +1822,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1285,7 +1287,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1347,13 +1349,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1373,12 +1378,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1409,19 +1421,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1440,7 +1453,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== compiler/parser/RdrHsSyn.hs ===================================== @@ -602,7 +602,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1076,7 +1076,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1113,7 +1117,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2064,7 +2072,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit b6bebdce0f217af8b6a249b3b6c2bd32dfa2b0b0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/35a4fdb9cb91a46df7d43778655383bd5e737574 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/35a4fdb9cb91a46df7d43778655383bd5e737574 You're receiving 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 17 20:16:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 17 Apr 2020 16:16:44 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 2 commits: Beta reduce state token Message-ID: <5e9a0eac53071_61673f8198ee100c5502863@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: a9333176 by Ben Gamari at 2020-04-17T18:19:39+00:00 Beta reduce state token - - - - - 0040f7cc by Ben Gamari at 2020-04-17T20:16:37+00:00 Fix warnings - - - - - 2 changed files: - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/CoreToStg/Prep.hs Changes: ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -51,7 +51,6 @@ import GHC.Core.FVs ( mkRuleInfo ) import GHC.Core.Rules ( lookupRule, getRules ) import GHC.Types.Basic ( TopLevelFlag(..), isNotTopLevel, isTopLevel, RecFlag(..), Arity ) -import GHC.Types.Unique ( hasKey ) import PrelNames ( keepAliveIdKey ) import MonadUtils ( mapAccumLM, liftIO ) import GHC.Types.Var ( isTyCoVar ) @@ -1906,14 +1905,11 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont , TyArg {as_arg_ty=arg_ty} , TyArg {as_arg_ty=arg_rep} ] <- rev_args + -- Extract type of second component of (# State# RealWorld, a #) + , Just (_, [_, _, _, ty']) <- splitTyConApp_maybe (contResultType cont) = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg ; f_body' <- simplExprC env' f_body cont ; let f' = Lam f_arg f_body' - -- Extract type of second component of (# State# RealWorld, a #) - ty' = case splitTyConApp_maybe (contResultType cont) of - Just (tc, [_, _, _, ty]) -> ty - Nothing -> panic "rebuildCall: Malformed (#,#) type" - ; let call' = mkApps (Var fun) [ mkTyArg arg_rep, mkTyArg arg_ty , mkTyArg (getRuntimeRep ty'), mkTyArg ty' ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -869,6 +869,10 @@ cpeApp top_env expr ; y <- newVar result_ty ; s1 <- newVar realWorldStatePrimTy ; s2 <- newVar realWorldStatePrimTy + -- Beta reduce + ; (floats0, k') <- case k of + Lam s body -> cpe_app (extendCorePrepEnvExpr env s s0) body [] 0 + _ -> cpe_app env k [CpeApp s0] 1 ; let touchId = mkPrimOpId TouchOp -- @stateResultAlt s y expr@ is a case alternative of the form, @@ -877,12 +881,13 @@ cpeApp top_env expr stateResultAlt stateVar resultVar rhs = (DataAlt (tupleDataCon Unboxed 2), [stateVar, resultVar], rhs) - expr = Case (App k s0) b0 out_ty [stateResultAlt s1 y rhs1] + expr = Case k' b0 out_ty [stateResultAlt s1 y rhs1] rhs1 = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, x, Var s1] in Case scrut s2 out_ty [(DEFAULT, [], rhs2)] rhs2 = mkApps (Var $ dataConWrapId $ tupleDataCon Unboxed 2) [mkTyArg voidRepTy, mkTyArg result_rep, mkTyArg realWorldStatePrimTy, mkTyArg result_ty, Var s2, Var y] - ; cpeBody env expr + ; (floats1, body) <- pprTrace "cpe_app" (ppr expr) $ cpeBody env expr + ; return (floats0 `appendFloats` floats1, body) } cpe_app _env (Var f) args _ | f `hasKey` keepAliveIdKey View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/75093e219f059a57ee4358eb3e787ff87d7fec13...0040f7ccaeb8a0f6945662c805eaa6c4bcc2023c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/75093e219f059a57ee4358eb3e787ff87d7fec13...0040f7ccaeb8a0f6945662c805eaa6c4bcc2023c You're receiving 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 17 22:48:45 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 17 Apr 2020 18:48:45 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: GHC.Core.Opt renaming Message-ID: <5e9a324da3e0_61673f8199536d945533637@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7f6e5d58 by Sylvain Henry at 2020-04-17T18:48:31-04:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 6d8e9459 by Sylvain Henry at 2020-04-17T18:48:31-04:00 Modules: SysTools (#13009) - - - - - 9f2b84ff by Sylvain Henry at 2020-04-17T18:48:31-04:00 Modules: Parser (#13009) - - - - - 45c57386 by Sylvain Henry at 2020-04-17T18:48:31-04:00 Modules: GHC.Builtin (#13009) - - - - - 99786795 by Sylvain Henry at 2020-04-17T18:48:31-04:00 Modules: GHC.Iface.Recomp (#13009) - - - - - 97a95916 by Sylvain Henry at 2020-04-17T18:48:31-04:00 Modules: Settings (#13009) Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - 8897f05b by Ben Gamari at 2020-04-17T18:48:32-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 3c81b94d by Ben Gamari at 2020-04-17T18:48:32-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - 4cfec5bf by Ben Gamari at 2020-04-17T18:48:32-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 2f1573e9 by Ben Gamari at 2020-04-17T18:48:32-04:00 Bump hsc2hs submodule - - - - - 15c5fdde by Ömer Sinan Ağacan at 2020-04-17T18:48:35-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bcb221d97a57d5b637e8e1ab9ea56b27c5800667...15c5fddeecc6c77021496c299a6f7b61fc9bf1fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bcb221d97a57d5b637e8e1ab9ea56b27c5800667...15c5fddeecc6c77021496c299a6f7b61fc9bf1fd You're receiving 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 18 04:19:14 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 00:19:14 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Change the fail operator argument of BindStmt to be a Maybe Message-ID: <5e9a7fc2af759_61673f8198ee100c5549061@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 9398de97 by John Ericson at 2020-04-18T00:19:03-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 52142930 by Ben Gamari at 2020-04-18T00:19:07-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 955b7f59 by Ben Gamari at 2020-04-18T00:19:07-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - 3a561961 by Ben Gamari at 2020-04-18T00:19:07-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - b452ab67 by Ben Gamari at 2020-04-18T00:19:07-04:00 Bump hsc2hs submodule - - - - - 37c89c05 by Ömer Sinan Ağacan at 2020-04-18T00:19:09-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl.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/15c5fddeecc6c77021496c299a6f7b61fc9bf1fd...37c89c05908dcdb692a5839509357bace3183bba -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15c5fddeecc6c77021496c299a6f7b61fc9bf1fd...37c89c05908dcdb692a5839509357bace3183bba You're receiving 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 18 09:49:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 05:49:43 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add a missing zonk in tcHsPartialType Message-ID: <5e9acd3773817_616765c7a28558249e@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5a7cdf21 by Simon Peyton Jones at 2020-04-18T05:49:32-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 324b5d2c by Ben Gamari at 2020-04-18T05:49:33-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 2ec2b610 by Ben Gamari at 2020-04-18T05:49:33-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - d14ef0a6 by Ben Gamari at 2020-04-18T05:49:33-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - 345d3282 by Ben Gamari at 2020-04-18T05:49:33-04:00 Bump hsc2hs submodule - - - - - 45186e46 by Ömer Sinan Ağacan at 2020-04-18T05:49:35-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 8 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Tc/Gen/HsType.hs - libraries/ghci/GHCi/FFI.hsc - + testsuite/tests/partial-sigs/should_compile/T18008.hs - + testsuite/tests/partial-sigs/should_compile/T18008.stderr - testsuite/tests/partial-sigs/should_compile/all.T - utils/hsc2hs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -26,19 +26,18 @@ stages: - testing # head.hackage correctness and compiler performance testing - deploy # push documentation -# N.B.Don't run on wip/ branches, instead on run on merge requests. -.only-default: &only-default - only: - - master - - /ghc-[0-9]+\.[0-9]+/ - - merge_requests - - tags - - web +workflow: + # N.B.Don't run on wip/ branches, instead on run on merge requests. + rules: + - if: $CI_MERGE_REQUEST_ID + - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' + - if: '$CI_PIPELINE_SOURCE == "web"' .nightly: &nightly - only: - variables: - - $NIGHTLY + rules: + - if: $NIGHTLY artifacts: when: always expire_in: 8 weeks @@ -50,9 +49,8 @@ stages: artifacts: when: always expire_in: 1 year - only: - variables: - - $RELEASE == "yes" + rules: + - if: '$RELEASE == "yes"' ############################################################ # Runner Tags @@ -86,13 +84,11 @@ ghc-linters: dependencies: [] tags: - lint - only: - refs: - - merge_requests + rules: + - if: $CI_MERGE_REQUEST_ID # Run mypy Python typechecker on linter scripts. lint-linters: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -103,7 +99,6 @@ lint-linters: # Check that .T files all parse by listing broken tests. lint-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" script: @@ -114,7 +109,6 @@ lint-testsuite: # Run mypy Python typechecker on testsuite driver typecheck-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -127,7 +121,6 @@ typecheck-testsuite: # accommodate, e.g., haddock changes not yet upstream) but not on `master` or # Marge jobs. .lint-submods: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -140,25 +133,14 @@ typecheck-testsuite: tags: - lint -lint-submods-marge: +lint-submods: extends: .lint-submods - only: - refs: - - merge_requests - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" - -lint-submods-mr: - extends: .lint-submods - # Allow failure since any necessary submodule patches may not be upstreamed - # yet. - allow_failure: true - only: - refs: - - merge_requests - except: - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" + # Allow failure on merge requests since any necessary submodule patches may + # not be upstreamed yet. + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' + allow_failure: false + - allow_failure: true lint-submods-branch: extends: .lint-submods @@ -166,13 +148,11 @@ lint-submods-branch: - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - git submodule foreach git remote update - submodchecker . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) - only: - refs: - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' .lint-changelogs: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" dependencies: [] @@ -185,15 +165,13 @@ lint-changelogs: extends: .lint-changelogs # Allow failure since this isn't a final release. allow_failure: true - only: - refs: - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' lint-release-changelogs: extends: .lint-changelogs - only: - refs: - - /ghc-[0-9]+\.[0-9]+\.[0-9]+-.*/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' ############################################################ @@ -201,7 +179,6 @@ lint-release-changelogs: ############################################################ .validate-hadrian: - <<: *only-default variables: FLAVOUR: "validate" script: @@ -250,7 +227,6 @@ validate-x86_64-linux-deb9-unreg-hadrian: TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" hadrian-ghc-in-ghci: - <<: *only-default stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" before_script: @@ -283,7 +259,6 @@ hadrian-ghc-in-ghci: ############################################################ .validate: - <<: *only-default variables: TEST_TYPE: test MAKE_ARGS: "-Werror" @@ -317,8 +292,8 @@ hadrian-ghc-in-ghci: # porting guide [1]. # [1] https://www.freebsd.org/doc/en/books/porters-handbook/using-iconv.html) 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" - GHC_VERSION: 8.6.3 - CABAL_INSTALL_VERSION: 3.0.0.0 + GHC_VERSION: 8.10.1 + CABAL_INSTALL_VERSION: 3.2.0.0 BIN_DIST_PREP_TAR_COMP: "ghc-x86_64-portbld-freebsd.tar.xz" TEST_ENV: "x86_64-freebsd" BUILD_FLAVOUR: "validate" @@ -334,10 +309,12 @@ hadrian-ghc-in-ghci: - cabal-cache - toolchain -# Disabled due to lack of builder capacity -.validate-x86_64-freebsd: +# Conditional due to lack of builder capacity +validate-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/' nightly-x86_64-freebsd: <<: *nightly @@ -414,7 +391,6 @@ validate-x86_64-darwin: # Disabled because of OS X CI capacity .validate-x86_64-darwin-hadrian: - <<: *only-default stage: full-build tags: - x86_64-darwin @@ -777,7 +753,6 @@ validate-x86_64-linux-fedora27: ############################################################ .build-windows: - <<: *only-default # For the reasons given in #17777 this build isn't reliable. allow_failure: true before_script: @@ -951,7 +926,6 @@ nightly-i386-windows: # See Note [Cleanup after shell executor] cleanup-darwin: - <<: *only-default stage: cleanup tags: - x86_64-darwin @@ -973,7 +947,6 @@ cleanup-darwin: ############################################################ doc-tarball: - <<: *only-default stage: packaging tags: - x86_64-linux @@ -1013,10 +986,10 @@ source-tarball: tags: - x86_64-linux image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - when: always dependencies: [] - only: - - tags + rules: + - if: $CI_COMMIT_TAG + when: always artifacts: paths: - ghc-*.tar.xz @@ -1043,7 +1016,6 @@ source-tarball: # pipeline. .hackage: - <<: *only-default stage: testing image: ghcci/x86_64-linux-deb9:0.2 tags: @@ -1060,9 +1032,8 @@ hackage: hackage-label: extends: .hackage - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/ + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' nightly-hackage: <<: *nightly @@ -1077,11 +1048,10 @@ perf-nofib: dependencies: - validate-x86_64-linux-deb9-dwarf image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - only: - refs: - - merge_requests - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: $CI_MERGE_REQUEST_ID + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' tags: - x86_64-linux script: @@ -1130,8 +1100,8 @@ pages: EOF - cp -f index.html public/doc - only: - - master + rules: + - if: '$CI_COMMIT_BRANCH == "master"' artifacts: paths: - public ===================================== .gitlab/ci.sh ===================================== @@ -139,12 +139,6 @@ function set_toolchain_paths() { export CABAL export HAPPY export ALEX - - # FIXME: Temporarily use ghc from ports - case "$(uname)" in - FreeBSD) GHC="/usr/local/bin/ghc" ;; - *) ;; - esac } # Extract GHC toolchain ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -732,6 +732,7 @@ tc_hs_type mode forall@(HsForAllTy { hst_fvf = fvf, hst_bndrs = hs_tvs m_telescope = Just (sep (map ppr hs_tvs)) ; emitResidualTvConstraint skol_info m_telescope tvs' tclvl wanted + -- See Note [Skolem escape and forall-types] ; return (mkForAllTys bndrs ty') } @@ -920,6 +921,26 @@ under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types +Note [Skolem escape and forall-types] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + f :: forall a. (forall kb (b :: kb). Proxy '[a, b]) -> () + +The Proxy '[a,b] forces a and b to have the same kind. But a's +kind must be bound outside the 'forall a', and hence escapes. +We discover this by building an implication constraint for +each forall. So the inner implication constraint will look like + forall kb (b::kb). kb ~ ka +where ka is a's kind. We can't unify these two, /even/ if ka is +unification variable, because it would be untouchable inside +this inner implication. + +That's what the pushLevelAndCaptureConstraints, plus subsequent +emitResidualTvConstraint is all about, when kind-checking +HsForAllTy. + +Note that we don't need to /simplify/ the constraints here +because we aren't generalising. We just capture them. -} {- ********************************************************************* @@ -2819,10 +2840,13 @@ kindGeneralizeAll ty = do { traceTc "kindGeneralizeAll" empty ; kindGeneralizeSome (const True) ty } -- | Specialized version of 'kindGeneralizeSome', but where no variables --- can be generalized. Use this variant when it is unknowable whether metavariables --- might later be constrained. --- See Note [Recipe for checking a signature] for why and where this --- function is needed. +-- can be generalized, but perhaps some may neeed to be promoted. +-- Use this variant when it is unknowable whether metavariables might +-- later be constrained. +-- +-- To see why this promotion is needed, see +-- Note [Recipe for checking a signature], and especially +-- Note [Promotion in signatures]. kindGeneralizeNone :: TcType -- needn't be zonked -> TcM () kindGeneralizeNone ty @@ -3160,7 +3184,7 @@ tcHsPartialSigType ctxt sig_ty ; return (wcs, wcx, theta, tau) } - -- No kind-generalization here: + -- No kind-generalization here, but perhaps some promotion ; kindGeneralizeNone (mkSpecForAllTys implicit_tvs $ mkSpecForAllTys explicit_tvs $ mkPhiTy theta $ @@ -3171,6 +3195,14 @@ tcHsPartialSigType ctxt sig_ty -- See Note [Extra-constraint holes in partial type signatures] ; emitNamedWildCardHoleConstraints wcs + -- Zonk, so that any nested foralls can "see" their occurrences + -- See Note [Checking partial type signatures], in + -- the bullet on Nested foralls. + ; implicit_tvs <- mapM zonkTcTyVarToTyVar implicit_tvs + ; explicit_tvs <- mapM zonkTcTyVarToTyVar explicit_tvs + ; theta <- mapM zonkTcType theta + ; tau <- zonkTcType tau + -- We return a proper (Name,TyVar) environment, to be sure that -- we bring the right name into scope in the function body. -- Test case: partial-sigs/should_compile/LocalDefinitionBug @@ -3179,7 +3211,7 @@ tcHsPartialSigType ctxt sig_ty -- NB: checkValidType on the final inferred type will be -- done later by checkInferredPolyId. We can't do it - -- here because we don't have a complete tuype to check + -- here because we don't have a complete type to check ; traceTc "tcHsPartialSigType" (ppr tv_prs) ; return (wcs, wcx, tv_prs, theta, tau) } @@ -3198,12 +3230,31 @@ tcPartialContext hs_theta {- Note [Checking partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See also Note [Recipe for checking a signature] +This Note is about tcHsPartialSigType. See also +Note [Recipe for checking a signature] When we have a partial signature like - f,g :: forall a. a -> _ + f :: forall a. a -> _ we do the following +* tcHsPartialSigType does not make quantified type (forall a. blah) + and then instantiate it -- it makes no sense to instantiate a type + with wildcards in it. Rather, tcHsPartialSigType just returns the + 'a' and the 'blah' separately. + + Nor, for the same reason, do we push a level in tcHsPartialSigType. + +* We instantiate 'a' to a unification variable, a TyVarTv, and /not/ + a skolem; hence the "_Tv" in bindExplicitTKBndrs_Tv. Consider + f :: forall a. a -> _ + g :: forall b. _ -> b + f = g + g = f + They are typechecked as a recursive group, with monomorphic types, + so 'a' and 'b' will get unified together. Very like kind inference + for mutually recursive data types (sans CUSKs or SAKS); see + Note [Cloning for tyvar binders] in GHC.Tc.Gen.HsType + * In GHC.Tc.Gen.Sig.tcUserSigType we return a PartialSig, which (unlike the companion CompleteSig) contains the original, as-yet-unchecked source-code LHsSigWcType @@ -3218,12 +3269,28 @@ we do the following g x = True It's really as if we'd written two distinct signatures. -* Note that we don't make quantified type (forall a. blah) and then - instantiate it -- it makes no sense to instantiate a type with - wildcards in it. Rather, tcHsPartialSigType just returns the - 'a' and the 'blah' separately. - - Nor, for the same reason, do we push a level in tcHsPartialSigType. +* Nested foralls. Consider + f :: forall b. (forall a. a -> _) -> b + We do /not/ allow the "_" to be instantiated to 'a'; but we do + (as before) allow it to be instantiated to the (top level) 'b'. + Why not? Because suppose + f x = (x True, x 'c') + We must instantiate that (forall a. a -> _) when typechecking + f's body, so we must know precisely where all the a's are; they + must not be hidden under (filled-in) unification variables! + + We achieve this in the usual way: we push a level at a forall, + so now the unification variable for the "_" can't unify with + 'a'. + +* Just as for ordinary signatures, we must zonk the type after + kind-checking it, to ensure that all the nested forall binders can + see their occurrenceds + + Just as for ordinary signatures, this zonk also gets any Refl casts + out of the way of instantiation. Example: #18008 had + foo :: (forall a. (Show a => blah) |> Refl) -> _ + and that Refl cast messed things up. See #18062. Note [Extra-constraint holes in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/ghci/GHCi/FFI.hsc ===================================== @@ -58,15 +58,29 @@ prepForeignCall cconv arg_types result_type = do cif <- mallocBytes (#const sizeof(ffi_cif)) let abi = convToABI cconv r <- ffi_prep_cif cif abi (fromIntegral n_args) (ffiType result_type) arg_arr - if (r /= fFI_OK) - then throwIO (ErrorCall ("prepForeignCallFailed: " ++ show r)) - else return (castPtr cif) + if r /= fFI_OK then + throwIO $ ErrorCall $ concat + [ "prepForeignCallFailed: ", strError r, + "(cconv: ", show cconv, + " arg tys: ", show arg_types, + " res ty: ", show result_type, ")" ] + else + return (castPtr cif) freeForeignCallInfo :: Ptr C_ffi_cif -> IO () freeForeignCallInfo p = do free ((#ptr ffi_cif, arg_types) p) free p +strError :: C_ffi_status -> String +strError r + | r == fFI_BAD_ABI + = "invalid ABI (FFI_BAD_ABI)" + | r == fFI_BAD_TYPEDEF + = "invalid type description (FFI_BAD_TYPEDEF)" + | otherwise + = "unknown error: " ++ show r + convToABI :: FFIConv -> C_ffi_abi convToABI FFICCall = fFI_DEFAULT_ABI #if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH) @@ -108,12 +122,10 @@ foreign import ccall "&ffi_type_float" ffi_type_float :: Ptr C_ffi_type foreign import ccall "&ffi_type_double" ffi_type_double :: Ptr C_ffi_type foreign import ccall "&ffi_type_pointer"ffi_type_pointer :: Ptr C_ffi_type -fFI_OK :: C_ffi_status -fFI_OK = (#const FFI_OK) ---fFI_BAD_ABI :: C_ffi_status ---fFI_BAD_ABI = (#const FFI_BAD_ABI) ---fFI_BAD_TYPEDEF :: C_ffi_status ---fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF) +fFI_OK, fFI_BAD_ABI, fFI_BAD_TYPEDEF :: C_ffi_status +fFI_OK = (#const FFI_OK) +fFI_BAD_ABI = (#const FFI_BAD_ABI) +fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF) fFI_DEFAULT_ABI :: C_ffi_abi fFI_DEFAULT_ABI = (#const FFI_DEFAULT_ABI) ===================================== testsuite/tests/partial-sigs/should_compile/T18008.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE PartialTypeSignatures #-} +module Bug where + +f :: (forall a. Show a => a -> String) -> _ +f s = s () + ===================================== testsuite/tests/partial-sigs/should_compile/T18008.stderr ===================================== @@ -0,0 +1,5 @@ + +T18008.hs:5:43: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_’ standing for ‘String’ + • In the type ‘(forall a. Show a => a -> String) -> _’ + In the type signature: f :: (forall a. Show a => a -> String) -> _ ===================================== testsuite/tests/partial-sigs/should_compile/all.T ===================================== @@ -95,3 +95,4 @@ test('T16334', normal, compile, ['']) test('T16728', normal, compile, ['']) test('T16728a', normal, compile, ['']) test('T16728b', normal, compile, ['']) +test('T18008', normal, compile, ['']) ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit dff4ed1acf9ebbdd004fc833a474dc8c16a90f5b +Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37c89c05908dcdb692a5839509357bace3183bba...45186e464a3f5a6d302debc930ef3376959ab707 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37c89c05908dcdb692a5839509357bace3183bba...45186e464a3f5a6d302debc930ef3376959ab707 You're receiving 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 18 16:57:33 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Sat, 18 Apr 2020 12:57:33 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] 50 commits: Do not panic on linker errors Message-ID: <5e9b317d33d67_61673f81ef22dee456048a5@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - 38cc55c6 by Alan Zimmerman at 2020-04-04T13:40:39+01:00 Proof of Concept implementation of in-tree API Annotations This MR introduces a possible machinery to introduce API Annotations into the TTG extension points. It is intended to be a concrete example for discussion. It still needs to process comments. ---- Work in progress, adding more TTG extensions for annotations. And fixing ppr round-trip tests by being able to blank out in-tree annotations, as done with SrcSpans. This is needed for the case of class Foo a where for which current ppr does not print the "where". Rename AA to AddApiAnn and AA to AddAnn Add XConPatIn and XConPatOut Rebase ---- First pass at bringing in LocatedA for API anns in locations Treatment of ECP in parsing is provisional at this stage, leads to some horribly stuff in Parser.y and RdrHsSyn. It is an extensive but not invasive change. I think (AZ). Locally it reports some parsing tests using less memory. Add ApiAnns to the HsExpr data structure. rebase. Change HsMatchContext and HsStmtContext to use an id, not a GhcPass parameter. Add ApiAnns to Hs/Types Rebase Rebased 2020-03-25 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan - - - - - 3a196931 by Alan Zimmerman at 2020-04-05T20:47:21+01:00 In-tree annotations: LHsDecl and LHsBind LocatedA - - - - - 85a2eb81 by Alan Zimmerman at 2020-04-06T20:35:11+01:00 WIP on in-tree annotations - - - - - 5851860d by Alan Zimmerman at 2020-04-11T10:58:16+01:00 in-tree annotations: LHsType is now LocatedA - - - - - 58854cb1 by Alan Zimmerman at 2020-04-11T18:01:37+01:00 FunDeps is now also a HS data type - - - - - 88bcece4 by Alan Zimmerman at 2020-04-14T21:23:09+01:00 WIP. Added LocatedA to Pat, Expr, Decl And worked some more through Parser.y - - - - - e47b27b8 by Alan Zimmerman at 2020-04-15T20:01:32+01:00 LStmt now Located - - - - - 18d70ea2 by Alan Zimmerman at 2020-04-18T17:56:13+01:00 Finished working through Parser.y, tests seem ok failures relate to annotations. - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/Switch/Implement.hs - compiler/GHC/Cmm/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8277c02e329408fdb2ad23fd55568630638306d...18d70ea2e803677f10042c6d13e1117c77ea951d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8277c02e329408fdb2ad23fd55568630638306d...18d70ea2e803677f10042c6d13e1117c77ea951d You're receiving 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 18 17:20:09 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 13:20:09 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Change the fail operator argument of BindStmt to be a Maybe Message-ID: <5e9b36c9392cb_616713503ee056101f7@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 20 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/ThToHs.hs - compiler/parser/Parser.y Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -1828,16 +1828,14 @@ data StmtLR idL idR body -- body should always be (LHs**** idR) -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnLarrow' -- For details on above see note [Api annotations] in ApiAnnotation - | BindStmt (XBindStmt idL idR body) -- Post typechecking, - -- result type of the function passed to bind; - -- that is, S in (>>=) :: Q -> (R -> S) -> T + | BindStmt (XBindStmt idL idR body) + -- ^ Post renaming has optional fail and bind / (>>=) operator. + -- Post typechecking, also has result type of the + -- function passed to bind; that is, S in (>>=) + -- :: Q -> (R -> S) -> T + -- See Note [The type of bind in Stmts] (LPat idL) body - (SyntaxExpr idR) -- The (>>=) operator; see Note [The type of bind in Stmts] - (SyntaxExpr idR) -- The fail operator - -- The fail operator is noSyntaxExpr - -- if the pattern match can't fail - -- See Note [NoSyntaxExpr] (2) -- | 'ApplicativeStmt' represents an applicative expression built with -- '<$>' and '<*>'. It is generated by the renamer, and is desugared into the @@ -1950,8 +1948,19 @@ data RecStmtTc = type instance XLastStmt (GhcPass _) (GhcPass _) b = NoExtField type instance XBindStmt (GhcPass _) GhcPs b = NoExtField -type instance XBindStmt (GhcPass _) GhcRn b = NoExtField -type instance XBindStmt (GhcPass _) GhcTc b = Type +type instance XBindStmt (GhcPass _) GhcRn b = XBindStmtRn +type instance XBindStmt (GhcPass _) GhcTc b = XBindStmtTc + +data XBindStmtRn = XBindStmtRn + { xbsrn_bindOp :: SyntaxExpr GhcRn + , xbsrn_failOp :: FailOperator GhcRn + } + +data XBindStmtTc = XBindStmtTc + { xbstc_bindOp :: SyntaxExpr GhcTc + , xbstc_boundResultType :: Type -- If (>>=) :: Q -> (R -> S) -> T, this is S + , xbstc_failOp :: FailOperator GhcTc + } type instance XApplicativeStmt (GhcPass _) GhcPs b = NoExtField type instance XApplicativeStmt (GhcPass _) GhcRn b = NoExtField @@ -1994,34 +2003,55 @@ data ParStmtBlock idL idR type instance XParStmtBlock (GhcPass pL) (GhcPass pR) = NoExtField type instance XXParStmtBlock (GhcPass pL) (GhcPass pR) = NoExtCon +-- | The fail operator +-- +-- This is used for `.. <-` "bind statments" in do notation, including +-- non-monadic "binds" in applicative. +-- +-- The fail operator is 'Just expr' if it potentially fail monadically. if the +-- pattern match cannot fail, or shouldn't fail monadically (regular incomplete +-- pattern exception), it is 'Nothing'. +-- +-- See Note [Monad fail : Rebindable syntax, overloaded strings] for the type of +-- expression in the 'Just' case, and why it is so. +-- +-- See Note [Failing pattern matches in Stmts] for which contexts for +-- '@BindStmt@'s should use the monadic fail and which shouldn't. +type FailOperator id = Maybe (SyntaxExpr id) + -- | Applicative Argument data ApplicativeArg idL = ApplicativeArgOne -- A single statement (BindStmt or BodyStmt) - { xarg_app_arg_one :: (XApplicativeArgOne idL) - , app_arg_pattern :: (LPat idL) -- WildPat if it was a BodyStmt (see below) - , arg_expr :: (LHsExpr idL) - , is_body_stmt :: Bool -- True <=> was a BodyStmt - -- False <=> was a BindStmt - -- See Note [Applicative BodyStmt] - , fail_operator :: (SyntaxExpr idL) -- The fail operator - -- The fail operator is needed if this is a BindStmt - -- where the pattern can fail. E.g.: - -- (Just a) <- stmt - -- The fail operator will be invoked if the pattern - -- match fails. - -- The fail operator is noSyntaxExpr - -- if the pattern match can't fail - -- See Note [NoSyntaxExpr] (2) + { xarg_app_arg_one :: XApplicativeArgOne idL + -- ^ The fail operator, after renaming + -- + -- The fail operator is needed if this is a BindStmt + -- where the pattern can fail. E.g.: + -- (Just a) <- stmt + -- The fail operator will be invoked if the pattern + -- match fails. + -- It is also used for guards in MonadComprehensions. + -- The fail operator is Nothing + -- if the pattern match can't fail + , app_arg_pattern :: LPat idL -- WildPat if it was a BodyStmt (see below) + , arg_expr :: LHsExpr idL + , is_body_stmt :: Bool + -- ^ True <=> was a BodyStmt, + -- False <=> was a BindStmt. + -- See Note [Applicative BodyStmt] } | ApplicativeArgMany -- do { stmts; return vars } - { xarg_app_arg_many :: (XApplicativeArgMany idL) + { xarg_app_arg_many :: XApplicativeArgMany idL , app_stmts :: [ExprLStmt idL] -- stmts - , final_expr :: (HsExpr idL) -- return (v1,..,vn), or just (v1,..,vn) - , bv_pattern :: (LPat idL) -- (v1,...,vn) + , final_expr :: HsExpr idL -- return (v1,..,vn), or just (v1,..,vn) + , bv_pattern :: LPat idL -- (v1,...,vn) } | XApplicativeArg !(XXApplicativeArg idL) -type instance XApplicativeArgOne (GhcPass _) = NoExtField +type instance XApplicativeArgOne GhcPs = NoExtField +type instance XApplicativeArgOne GhcRn = FailOperator GhcRn +type instance XApplicativeArgOne GhcTc = FailOperator GhcTc + type instance XApplicativeArgMany (GhcPass _) = NoExtField type instance XXApplicativeArg (GhcPass _) = NoExtCon @@ -2212,7 +2242,7 @@ pprStmt (LastStmt _ expr m_dollar_stripped _) Just False -> text "return" Nothing -> empty) <+> ppr expr -pprStmt (BindStmt _ pat expr _ _) = hsep [ppr pat, larrow, ppr expr] +pprStmt (BindStmt _ pat expr) = hsep [ppr pat, larrow, ppr expr] pprStmt (LetStmt _ (L _ binds)) = hsep [text "let", pprBinds binds] pprStmt (BodyStmt _ expr _ _) = ppr expr pprStmt (ParStmt _ stmtss _ _) = sep (punctuate (text " | ") (map ppr stmtss)) @@ -2247,13 +2277,12 @@ pprStmt (ApplicativeStmt _ args mb_join) flattenStmt stmt = [ppr stmt] flattenArg :: forall a . (a, ApplicativeArg (GhcPass idL)) -> [SDoc] - flattenArg (_, ApplicativeArgOne _ pat expr isBody _) + flattenArg (_, ApplicativeArgOne _ pat expr isBody) | isBody = -- See Note [Applicative BodyStmt] [ppr (BodyStmt (panic "pprStmt") expr noSyntaxExpr noSyntaxExpr :: ExprStmt (GhcPass idL))] | otherwise = - [ppr (BindStmt (panic "pprStmt") pat expr noSyntaxExpr noSyntaxExpr - :: ExprStmt (GhcPass idL))] + [ppr (BindStmt (panic "pprStmt") pat expr :: ExprStmt (GhcPass idL))] flattenArg (_, ApplicativeArgMany _ stmts _ _) = concatMap flattenStmt stmts @@ -2273,13 +2302,12 @@ instance (OutputableBndrId idL) ppr = pprArg pprArg :: forall idL . (OutputableBndrId idL) => ApplicativeArg (GhcPass idL) -> SDoc -pprArg (ApplicativeArgOne _ pat expr isBody _) +pprArg (ApplicativeArgOne _ pat expr isBody) | isBody = -- See Note [Applicative BodyStmt] ppr (BodyStmt (panic "pprStmt") expr noSyntaxExpr noSyntaxExpr :: ExprStmt (GhcPass idL)) | otherwise = - ppr (BindStmt (panic "pprStmt") pat expr noSyntaxExpr noSyntaxExpr - :: ExprStmt (GhcPass idL)) + ppr (BindStmt (panic "pprStmt") pat expr :: ExprStmt (GhcPass idL)) pprArg (ApplicativeArgMany _ stmts return pat) = ppr pat <+> text "<-" <+> ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -334,6 +334,9 @@ deriving instance Data PendingTcSplice deriving instance Data SyntaxExprRn deriving instance Data SyntaxExprTc +deriving instance Data XBindStmtRn +deriving instance Data XBindStmtTc + -- --------------------------------------------------------------------- -- Data derivations from GHC.Hs.Lit ------------------------------------ ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -69,7 +69,8 @@ module GHC.Hs.Utils( nlHsAppTy, nlHsAppKindTy, nlHsTyVar, nlHsFunTy, nlHsParTy, nlHsTyConApp, -- * Stmts - mkTransformStmt, mkTransformByStmt, mkBodyStmt, mkBindStmt, mkTcBindStmt, + mkTransformStmt, mkTransformByStmt, mkBodyStmt, + mkPsBindStmt, mkRnBindStmt, mkTcBindStmt, mkLastStmt, emptyTransStmt, mkGroupUsingStmt, mkGroupByUsingStmt, emptyRecStmt, emptyRecStmtName, emptyRecStmtId, mkRecStmt, @@ -259,10 +260,10 @@ mkLastStmt :: IsPass idR => Located (bodyR (GhcPass idR)) -> StmtLR (GhcPass idL) (GhcPass idR) (Located (bodyR (GhcPass idR))) mkBodyStmt :: Located (bodyR GhcPs) -> StmtLR (GhcPass idL) GhcPs (Located (bodyR GhcPs)) -mkBindStmt :: IsPass idR => (XBindStmt (GhcPass idL) (GhcPass idR) - (Located (bodyR (GhcPass idR))) ~ NoExtField) - => LPat (GhcPass idL) -> Located (bodyR (GhcPass idR)) - -> StmtLR (GhcPass idL) (GhcPass idR) (Located (bodyR (GhcPass idR))) +mkPsBindStmt :: LPat GhcPs -> Located (bodyR GhcPs) + -> StmtLR GhcPs GhcPs (Located (bodyR GhcPs)) +mkRnBindStmt :: LPat GhcRn -> Located (bodyR GhcRn) + -> StmtLR GhcRn GhcRn (Located (bodyR GhcRn)) mkTcBindStmt :: LPat GhcTc -> Located (bodyR GhcTc) -> StmtLR GhcTc GhcTc (Located (bodyR GhcTc)) @@ -320,9 +321,9 @@ mkGroupByUsingStmt ss b u = emptyTransStmt { trS_form = GroupForm, trS_stmts = s mkLastStmt body = LastStmt noExtField body Nothing noSyntaxExpr mkBodyStmt body = BodyStmt noExtField body noSyntaxExpr noSyntaxExpr -mkBindStmt pat body - = BindStmt noExtField pat body noSyntaxExpr noSyntaxExpr -mkTcBindStmt pat body = BindStmt unitTy pat body noSyntaxExpr noSyntaxExpr +mkPsBindStmt pat body = BindStmt noExtField pat body +mkRnBindStmt pat body = BindStmt (XBindStmtRn { xbsrn_bindOp = noSyntaxExpr, xbsrn_failOp = Nothing }) pat body +mkTcBindStmt pat body = BindStmt (XBindStmtTc { xbstc_bindOp = noSyntaxExpr, xbstc_boundResultType =unitTy, xbstc_failOp = Nothing }) pat body -- don't use placeHolderTypeTc above, because that panics during zonking emptyRecStmt' :: forall idL idR body. IsPass idR @@ -1059,7 +1060,7 @@ collectLStmtBinders = collectStmtBinders . unLoc collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? -collectStmtBinders (BindStmt _ pat _ _ _) = collectPatBinders pat +collectStmtBinders (BindStmt _ pat _) = collectPatBinders pat collectStmtBinders (LetStmt _ binds) = collectLocalBinders (unLoc binds) collectStmtBinders (BodyStmt {}) = [] collectStmtBinders (LastStmt {}) = [] @@ -1349,7 +1350,7 @@ lStmtsImplicits = hs_lstmts hs_stmt :: StmtLR GhcRn (GhcPass idR) (Located (body (GhcPass idR))) -> [(SrcSpan, [Name])] - hs_stmt (BindStmt _ pat _ _ _) = lPatImplicits pat + hs_stmt (BindStmt _ pat _) = lPatImplicits pat hs_stmt (ApplicativeStmt _ args _) = concatMap do_arg args where do_arg (_, ApplicativeArgOne { app_arg_pattern = pat }) = lPatImplicits pat do_arg (_, ApplicativeArgMany { app_stmts = stmts }) = hs_lstmts stmts ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -866,7 +866,7 @@ dsCmdStmt ids local_vars out_ids (BodyStmt c_ty cmd _ _) env_ids = do -- It would be simpler and more consistent to do this using second, -- but that's likely to be defined in terms of first. -dsCmdStmt ids local_vars out_ids (BindStmt _ pat cmd _ _) env_ids = do +dsCmdStmt ids local_vars out_ids (BindStmt _ pat cmd) env_ids = do let pat_ty = hsLPatType pat (core_cmd, fv_cmd, env_ids1) <- dsfixCmd ids local_vars unitTy pat_ty cmd let pat_vars = mkVarSet (collectPatBinders pat) ===================================== compiler/GHC/HsToCore/Coverage.hs ===================================== @@ -709,12 +709,16 @@ addTickStmt _isGuard (LastStmt x e noret ret) = do (addTickLHsExpr e) (pure noret) (addTickSyntaxExpr hpcSrcSpan ret) -addTickStmt _isGuard (BindStmt x pat e bind fail) = do - liftM4 (BindStmt x) +addTickStmt _isGuard (BindStmt xbs pat e) = do + liftM4 (\b f -> BindStmt $ XBindStmtTc + { xbstc_bindOp = b + , xbstc_boundResultType = xbstc_boundResultType xbs + , xbstc_failOp = f + }) + (addTickSyntaxExpr hpcSrcSpan (xbstc_bindOp xbs)) + (mapM (addTickSyntaxExpr hpcSrcSpan) (xbstc_failOp xbs)) (addTickLPat pat) (addTickLHsExprRHS e) - (addTickSyntaxExpr hpcSrcSpan bind) - (addTickSyntaxExpr hpcSrcSpan fail) addTickStmt isGuard (BodyStmt x e bind' guard') = do liftM3 (BodyStmt x) (addTick isGuard e) @@ -763,12 +767,12 @@ addTickApplicativeArg addTickApplicativeArg isGuard (op, arg) = liftM2 (,) (addTickSyntaxExpr hpcSrcSpan op) (addTickArg arg) where - addTickArg (ApplicativeArgOne x pat expr isBody fail) = - (ApplicativeArgOne x) - <$> addTickLPat pat + addTickArg (ApplicativeArgOne m_fail pat expr isBody) = + ApplicativeArgOne + <$> mapM (addTickSyntaxExpr hpcSrcSpan) m_fail + <*> addTickLPat pat <*> addTickLHsExpr expr <*> pure isBody - <*> addTickSyntaxExpr hpcSrcSpan fail addTickArg (ApplicativeArgMany x stmts ret pat) = (ApplicativeArgMany x) <$> addTickLStmts isGuard stmts @@ -938,12 +942,10 @@ addTickLCmdStmts' lstmts res binders = collectLStmtsBinders lstmts addTickCmdStmt :: Stmt GhcTc (LHsCmd GhcTc) -> TM (Stmt GhcTc (LHsCmd GhcTc)) -addTickCmdStmt (BindStmt x pat c bind fail) = do - liftM4 (BindStmt x) +addTickCmdStmt (BindStmt x pat c) = do + liftM2 (BindStmt x) (addTickLPat pat) (addTickLHsCmd c) - (return bind) - (return fail) addTickCmdStmt (LastStmt x c noret ret) = do liftM3 (LastStmt x) (addTickLHsCmd c) ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -933,24 +933,24 @@ dsDo stmts = do { rest <- goL stmts ; dsLocalBinds binds rest } - go _ (BindStmt res1_ty pat rhs bind_op fail_op) stmts + go _ (BindStmt xbs pat rhs) stmts = do { body <- goL stmts ; rhs' <- dsLExpr rhs ; var <- selectSimpleMatchVarL pat ; match <- matchSinglePatVar var (StmtCtxt DoExpr) pat - res1_ty (cantFailMatchResult body) - ; match_code <- dsHandleMonadicFailure pat match fail_op - ; dsSyntaxExpr bind_op [rhs', Lam var match_code] } + (xbstc_boundResultType xbs) (cantFailMatchResult body) + ; match_code <- dsHandleMonadicFailure pat match (xbstc_failOp xbs) + ; dsSyntaxExpr (xbstc_bindOp xbs) [rhs', Lam var match_code] } go _ (ApplicativeStmt body_ty args mb_join) stmts = do { let (pats, rhss) = unzip (map (do_arg . snd) args) - do_arg (ApplicativeArgOne _ pat expr _ fail_op) = + do_arg (ApplicativeArgOne fail_op pat expr _) = ((pat, fail_op), dsLExpr expr) do_arg (ApplicativeArgMany _ stmts ret pat) = - ((pat, noSyntaxExpr), dsDo (stmts ++ [noLoc $ mkLastStmt (noLoc ret)])) + ((pat, Nothing), dsDo (stmts ++ [noLoc $ mkLastStmt (noLoc ret)])) ; rhss' <- sequence rhss @@ -981,9 +981,14 @@ dsDo stmts , recS_ret_ty = body_ty} }) stmts = goL (new_bind_stmt : stmts) -- rec_ids can be empty; eg rec { print 'x' } where - new_bind_stmt = L loc $ BindStmt bind_ty (mkBigLHsPatTupId later_pats) - mfix_app bind_op - noSyntaxExpr -- Tuple cannot fail + new_bind_stmt = L loc $ BindStmt + XBindStmtTc + { xbstc_bindOp = bind_op + , xbstc_boundResultType = bind_ty + , xbstc_failOp = Nothing -- Tuple cannot fail + } + (mkBigLHsPatTupId later_pats) + mfix_app tup_ids = rec_ids ++ filterOut (`elem` rec_ids) later_ids tup_ty = mkBigCoreTupTy (map idType tup_ids) -- Deals with singleton case @@ -1009,17 +1014,26 @@ dsDo stmts go _ (ParStmt {}) _ = panic "dsDo ParStmt" go _ (TransStmt {}) _ = panic "dsDo TransStmt" -dsHandleMonadicFailure :: LPat GhcTc -> MatchResult -> SyntaxExpr GhcTc -> DsM CoreExpr +dsHandleMonadicFailure :: LPat GhcTc -> MatchResult -> FailOperator GhcTc -> DsM CoreExpr -- In a do expression, pattern-match failure just calls -- the monadic 'fail' rather than throwing an exception -dsHandleMonadicFailure pat match fail_op - | matchCanFail match - = do { dflags <- getDynFlags - ; fail_msg <- mkStringExpr (mk_fail_msg dflags pat) - ; fail_expr <- dsSyntaxExpr fail_op [fail_msg] - ; extractMatchResult match fail_expr } - | otherwise - = extractMatchResult match (error "It can't fail") +dsHandleMonadicFailure pat match m_fail_op + | matchCanFail match = do + fail_op <- case m_fail_op of + -- Note that (non-monadic) list comprehension, pattern guards, etc could + -- have fallible bindings without an explicit failure op, but this is + -- handled elsewhere. See Note [Failing pattern matches in Stmts] the + -- breakdown of regular and special binds. + Nothing -> pprPanic "missing fail op" $ + text "Pattern match:" <+> ppr pat <+> + text "is failable, and fail_expr was left unset" + Just fail_op -> pure fail_op + dflags <- getDynFlags + fail_msg <- mkStringExpr (mk_fail_msg dflags pat) + fail_expr <- dsSyntaxExpr fail_op [fail_msg] + extractMatchResult match fail_expr + | otherwise = + extractMatchResult match (error "It can't fail") mk_fail_msg :: DynFlags -> Located e -> String mk_fail_msg dflags pat = "Pattern match failure in do expression at " ++ ===================================== compiler/GHC/HsToCore/Expr.hs-boot ===================================== @@ -1,5 +1,5 @@ module GHC.HsToCore.Expr where -import GHC.Hs ( HsExpr, LHsExpr, LHsLocalBinds, LPat, SyntaxExpr ) +import GHC.Hs ( HsExpr, LHsExpr, LHsLocalBinds, LPat, SyntaxExpr, FailOperator ) import GHC.HsToCore.Monad ( DsM, MatchResult ) import GHC.Core ( CoreExpr ) import GHC.Hs.Extension ( GhcTc) @@ -9,4 +9,4 @@ dsLExpr, dsLExprNoLP :: LHsExpr GhcTc -> DsM CoreExpr dsSyntaxExpr :: SyntaxExpr GhcTc -> [CoreExpr] -> DsM CoreExpr dsLocalBinds :: LHsLocalBinds GhcTc -> CoreExpr -> DsM CoreExpr -dsHandleMonadicFailure :: LPat GhcTc -> MatchResult -> SyntaxExpr GhcTc -> DsM CoreExpr +dsHandleMonadicFailure :: LPat GhcTc -> MatchResult -> FailOperator GhcTc -> DsM CoreExpr ===================================== compiler/GHC/HsToCore/GuardedRHSs.hs ===================================== @@ -122,7 +122,7 @@ matchGuards (LetStmt _ binds : stmts) ctx rhs rhs_ty = do -- so we can't desugar the bindings without the -- body expression in hand -matchGuards (BindStmt _ pat bind_rhs _ _ : stmts) ctx rhs rhs_ty = do +matchGuards (BindStmt _ pat bind_rhs : stmts) ctx rhs rhs_ty = do let upat = unLoc pat match_var <- selectMatchVar upat ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -241,7 +241,7 @@ deListComp (stmt@(TransStmt {}) : quals) list = do (inner_list_expr, pat) <- dsTransStmt stmt deBindComp pat inner_list_expr quals list -deListComp (BindStmt _ pat list1 _ _ : quals) core_list2 = do -- rule A' above +deListComp (BindStmt _ pat list1 : quals) core_list2 = do -- rule A' above core_list1 <- dsLExprNoLP list1 deBindComp pat core_list1 quals core_list2 @@ -349,7 +349,7 @@ dfListComp c_id n_id (stmt@(TransStmt {}) : quals) = do -- Anyway, we bind the newly grouped list via the generic binding function dfBindComp c_id n_id (pat, inner_list_expr) quals -dfListComp c_id n_id (BindStmt _ pat list1 _ _ : quals) = do +dfListComp c_id n_id (BindStmt _ pat list1 : quals) = do -- evaluate the two lists core_list1 <- dsLExpr list1 @@ -495,9 +495,9 @@ dsMcStmt (LetStmt _ binds) stmts ; dsLocalBinds binds rest } -- [ .. | a <- m, stmts ] -dsMcStmt (BindStmt bind_ty pat rhs bind_op fail_op) stmts +dsMcStmt (BindStmt xbs pat rhs) stmts = do { rhs' <- dsLExpr rhs - ; dsMcBindStmt pat rhs' bind_op fail_op bind_ty stmts } + ; dsMcBindStmt pat rhs' (xbstc_bindOp xbs) (xbstc_failOp xbs) (xbstc_boundResultType xbs) stmts } -- Apply `guard` to the `exp` expression -- @@ -585,7 +585,7 @@ dsMcStmt (ParStmt bind_ty blocks mzip_op bind_op) stmts_rest mkBoxedTupleTy [t1,t2])) exps_w_tys - ; dsMcBindStmt pat rhs bind_op noSyntaxExpr bind_ty stmts_rest } + ; dsMcBindStmt pat rhs bind_op Nothing bind_ty stmts_rest } where ds_inner :: ParStmtBlock GhcTc GhcTc -> DsM (CoreExpr, Type) ds_inner (ParStmtBlock _ stmts bndrs return_op) @@ -609,7 +609,7 @@ matchTuple ids body dsMcBindStmt :: LPat GhcTc -> CoreExpr -- ^ the desugared rhs of the bind statement -> SyntaxExpr GhcTc - -> SyntaxExpr GhcTc + -> Maybe (SyntaxExpr GhcTc) -> Type -- ^ S in (>>=) :: Q -> (R -> S) -> T -> [ExprLStmt GhcTc] -> DsM CoreExpr ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -660,7 +660,7 @@ translateGuard :: FamInstEnvs -> GuardStmt GhcTc -> DsM GrdVec translateGuard fam_insts guard = case guard of BodyStmt _ e _ _ -> translateBoolGuard e LetStmt _ binds -> translateLet (unLoc binds) - BindStmt _ p e _ _ -> translateBind fam_insts p e + BindStmt _ p e -> translateBind fam_insts p e LastStmt {} -> panic "translateGuard LastStmt" ParStmt {} -> panic "translateGuard ParStmt" TransStmt {} -> panic "translateGuard TransStmt" ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1613,7 +1613,7 @@ repLSts :: [LStmt GhcRn (LHsExpr GhcRn)] -> MetaM ([GenSymBind], [Core (M TH.Stm repLSts stmts = repSts (map unLoc stmts) repSts :: [Stmt GhcRn (LHsExpr GhcRn)] -> MetaM ([GenSymBind], [Core (M TH.Stmt)]) -repSts (BindStmt _ p e _ _ : ss) = +repSts (BindStmt _ p e : ss) = do { e2 <- repLE e ; ss1 <- mkGenSyms (collectPatBinders p) ; addBinds ss1 $ do { ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1049,7 +1049,7 @@ instance ( a ~ GhcPass p LastStmt _ body _ _ -> [ toHie body ] - BindStmt _ pat body _ _ -> + BindStmt _ pat body -> [ toHie $ PS (getRealSpan $ getLoc body) scope NoScope pat , toHie body ] @@ -1174,7 +1174,7 @@ instance ( a ~ GhcPass p , Data (StmtLR a a (Located (HsExpr a))) , Data (HsLocalBinds a) ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where - toHie (RS sc (ApplicativeArgOne _ pat expr _ _)) = concatM + toHie (RS sc (ApplicativeArgOne _ pat expr _)) = concatM [ toHie $ PS Nothing sc NoScope pat , toHie expr ] ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -573,7 +573,7 @@ methodNamesLStmt = methodNamesStmt . unLoc methodNamesStmt :: StmtLR GhcRn GhcRn (LHsCmd GhcRn) -> FreeVars methodNamesStmt (LastStmt _ cmd _ _) = methodNamesLCmd cmd methodNamesStmt (BodyStmt _ cmd _ _) = methodNamesLCmd cmd -methodNamesStmt (BindStmt _ _ cmd _ _) = methodNamesLCmd cmd +methodNamesStmt (BindStmt _ _ cmd) = methodNamesLCmd cmd methodNamesStmt (RecStmt { recS_stmts = stmts }) = methodNamesStmts stmts `addOneFV` loopAName methodNamesStmt (LetStmt {}) = emptyFVs @@ -760,8 +760,11 @@ Many things desugar to HsStmts including monadic things like `do` and `mdo` statements, pattern guards, and list comprehensions (see 'HsStmtContext' for an exhaustive list). How we deal with pattern match failure is context-dependent. - * In the case of list comprehensions and pattern guards we don't need any 'fail' - function; the desugarer ignores the fail function field of 'BindStmt' entirely. + * In the case of list comprehensions and pattern guards we don't need any + 'fail' function; the desugarer ignores the fail function of 'BindStmt' + entirely. So, for list comprehensions, the fail function is set to 'Nothing' + for clarity. + * In the case of monadic contexts (e.g. monad comprehensions, do, and mdo expressions) we want pattern match failure to be desugared to the appropriate 'fail' function (either that of Monad or MonadFail, depending on whether @@ -812,7 +815,7 @@ rnStmt ctxt rnBody (L loc (BodyStmt _ body _ _)) thing_inside ; return ( ([(L loc (BodyStmt noExtField body' then_op guard_op), fv_expr)] , thing), fv_expr `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) } -rnStmt ctxt rnBody (L loc (BindStmt _ pat body _ _)) thing_inside +rnStmt ctxt rnBody (L loc (BindStmt _ pat body)) thing_inside = do { (body', fv_expr) <- rnBody body -- The binders do not scope over the expression ; (bind_op, fvs1) <- lookupStmtName ctxt bindMName @@ -821,8 +824,8 @@ rnStmt ctxt rnBody (L loc (BindStmt _ pat body _ _)) thing_inside ; rnPat (StmtCtxt ctxt) pat $ \ pat' -> do { (thing, fvs3) <- thing_inside (collectPatBinders pat') - ; return (( [( L loc (BindStmt noExtField pat' body' bind_op fail_op) - , fv_expr )] + ; let xbsrn = XBindStmtRn { xbsrn_bindOp = bind_op, xbsrn_failOp = fail_op } + ; return (( [( L loc (BindStmt xbsrn pat' body'), fv_expr )] , thing), fv_expr `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) }} -- fv_expr shouldn't really be filtered by the rnPatsAndThen @@ -1077,11 +1080,11 @@ rn_rec_stmt_lhs _ (L loc (BodyStmt _ body a b)) rn_rec_stmt_lhs _ (L loc (LastStmt _ body noret a)) = return [(L loc (LastStmt noExtField body noret a), emptyFVs)] -rn_rec_stmt_lhs fix_env (L loc (BindStmt _ pat body a b)) +rn_rec_stmt_lhs fix_env (L loc (BindStmt _ pat body)) = do -- should the ctxt be MDo instead? (pat', fv_pat) <- rnBindPat (localRecNameMaker fix_env) pat - return [(L loc (BindStmt noExtField pat' body a b), fv_pat)] + return [(L loc (BindStmt noExtField pat' body), fv_pat)] rn_rec_stmt_lhs _ (L _ (LetStmt _ (L _ binds@(HsIPBinds {})))) = failWith (badIpBinds (text "an mdo expression") binds) @@ -1144,7 +1147,7 @@ rn_rec_stmt rnBody _ (L loc (BodyStmt _ body _ _), _) ; return [(emptyNameSet, fvs `plusFV` fvs1, emptyNameSet, L loc (BodyStmt noExtField body' then_op noSyntaxExpr))] } -rn_rec_stmt rnBody _ (L loc (BindStmt _ pat' body _ _), fv_pat) +rn_rec_stmt rnBody _ (L loc (BindStmt _ pat' body), fv_pat) = do { (body', fv_expr) <- rnBody body ; (bind_op, fvs1) <- lookupSyntax bindMName @@ -1152,8 +1155,9 @@ rn_rec_stmt rnBody _ (L loc (BindStmt _ pat' body _ _), fv_pat) ; let bndrs = mkNameSet (collectPatBinders pat') fvs = fv_expr `plusFV` fv_pat `plusFV` fvs1 `plusFV` fvs2 + ; let xbsrn = XBindStmtRn { xbsrn_bindOp = bind_op, xbsrn_failOp = fail_op } ; return [(bndrs, fvs, bndrs `intersectNameSet` fvs, - L loc (BindStmt noExtField pat' body' bind_op fail_op))] } + L loc (BindStmt xbsrn pat' body'))] } rn_rec_stmt _ _ (L _ (LetStmt _ (L _ binds@(HsIPBinds {}))), _) = failWith (badIpBinds (text "an mdo expression") binds) @@ -1645,27 +1649,27 @@ stmtTreeToStmts -- In the spec, but we do it here rather than in the desugarer, -- because we need the typechecker to typecheck the <$> form rather than -- the bind form, which would give rise to a Monad constraint. -stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BindStmt _ pat rhs _ fail_op), _)) +stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BindStmt xbs pat rhs), _)) tail _tail_fvs | not (isStrictPattern pat), (False,tail') <- needJoin monad_names tail -- See Note [ApplicativeDo and strict patterns] = mkApplicativeStmt ctxt [ApplicativeArgOne - { xarg_app_arg_one = noExtField + { xarg_app_arg_one = xbsrn_failOp xbs , app_arg_pattern = pat , arg_expr = rhs , is_body_stmt = False - , fail_operator = fail_op}] + }] False tail' stmtTreeToStmts monad_names ctxt (StmtTreeOne (L _ (BodyStmt _ rhs _ _),_)) tail _tail_fvs | (False,tail') <- needJoin monad_names tail = mkApplicativeStmt ctxt [ApplicativeArgOne - { xarg_app_arg_one = noExtField + { xarg_app_arg_one = Nothing , app_arg_pattern = nlWildPatName , arg_expr = rhs , is_body_stmt = True - , fail_operator = noSyntaxExpr}] False tail' + }] False tail' stmtTreeToStmts _monad_names _ctxt (StmtTreeOne (s,_)) tail _tail_fvs = return (s : tail, emptyNameSet) @@ -1688,21 +1692,19 @@ stmtTreeToStmts monad_names ctxt (StmtTreeApplicative trees) tail tail_fvs = do (stmts, fvs) <- mkApplicativeStmt ctxt stmts' need_join tail' return (stmts, unionNameSets (fvs:fvss)) where - stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BindStmt _ pat exp _ fail_op), _)) + stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BindStmt xbs pat exp), _)) = return (ApplicativeArgOne - { xarg_app_arg_one = noExtField + { xarg_app_arg_one = xbsrn_failOp xbs , app_arg_pattern = pat , arg_expr = exp , is_body_stmt = False - , fail_operator = fail_op }, emptyFVs) stmtTreeArg _ctxt _tail_fvs (StmtTreeOne (L _ (BodyStmt _ exp _ _), _)) = return (ApplicativeArgOne - { xarg_app_arg_one = noExtField + { xarg_app_arg_one = Nothing , app_arg_pattern = nlWildPatName , arg_expr = exp , is_body_stmt = True - , fail_operator = noSyntaxExpr }, emptyFVs) stmtTreeArg ctxt tail_fvs tree = do let stmts = flattenStmtTree tree @@ -1779,7 +1781,7 @@ segments stmts = map fst $ merge $ reverse $ map reverse $ walk (reverse stmts) pvars = mkNameSet (collectStmtBinders (unLoc stmt)) isStrictPatternBind :: ExprLStmt GhcRn -> Bool - isStrictPatternBind (L _ (BindStmt _ pat _ _ _)) = isStrictPattern pat + isStrictPatternBind (L _ (BindStmt _ pat _)) = isStrictPattern pat isStrictPatternBind _ = False {- @@ -1880,9 +1882,9 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- strict patterns though; splitSegments expects that if we return Just -- then we have actually done some splitting. Otherwise it will go into -- an infinite loop (#14163). - go lets indep bndrs ((L loc (BindStmt _ pat body bind_op fail_op), fvs): rest) + go lets indep bndrs ((L loc (BindStmt xbs pat body), fvs): rest) | isEmptyNameSet (bndrs `intersectNameSet` fvs) && not (isStrictPattern pat) - = go lets ((L loc (BindStmt noExtField pat body bind_op fail_op), fvs) : indep) + = go lets ((L loc (BindStmt xbs pat body), fvs) : indep) bndrs' rest where bndrs' = bndrs `unionNameSet` mkNameSet (collectPatBinders pat) -- If we encounter a LetStmt that doesn't depend on a BindStmt in this @@ -2127,16 +2129,16 @@ badIpBinds what binds monadFailOp :: LPat GhcPs -> HsStmtContext GhcRn - -> RnM (SyntaxExpr GhcRn, FreeVars) + -> RnM (FailOperator GhcRn, FreeVars) monadFailOp pat ctxt -- If the pattern is irrefutable (e.g.: wildcard, tuple, ~pat, etc.) -- we should not need to fail. - | isIrrefutableHsPat pat = return (noSyntaxExpr, emptyFVs) + | isIrrefutableHsPat pat = return (Nothing, emptyFVs) -- For non-monadic contexts (e.g. guard patterns, list - -- comprehensions, etc.) we should not need to fail. See Note - -- [Failing pattern matches in Stmts] - | not (isMonadFailStmtContext ctxt) = return (noSyntaxExpr, emptyFVs) + -- comprehensions, etc.) we should not need to fail, or failure is handled in + -- a different way. See Note [Failing pattern matches in Stmts]. + | not (isMonadFailStmtContext ctxt) = return (Nothing, emptyFVs) | otherwise = getMonadFailOp @@ -2164,11 +2166,12 @@ So, in this case, we synthesize the function (rather than plain 'fail') for the 'fail' operation. This is done in 'getMonadFailOp'. -} -getMonadFailOp :: RnM (SyntaxExpr GhcRn, FreeVars) -- Syntax expr fail op +getMonadFailOp :: RnM (FailOperator GhcRn, FreeVars) -- Syntax expr fail op getMonadFailOp = do { xOverloadedStrings <- fmap (xopt LangExt.OverloadedStrings) getDynFlags ; xRebindableSyntax <- fmap (xopt LangExt.RebindableSyntax) getDynFlags - ; reallyGetMonadFailOp xRebindableSyntax xOverloadedStrings + ; (fail, fvs) <- reallyGetMonadFailOp xRebindableSyntax xOverloadedStrings + ; return (Just fail, fvs) } where reallyGetMonadFailOp rebindableSyntax overloadedStrings ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -832,7 +832,7 @@ gen_Ix_binds loc tycon = do where stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed - mk_qual a b c = noLoc $ mkBindStmt (nlVarPat c) + mk_qual a b c = noLoc $ mkPsBindStmt (nlVarPat c) (nlHsApp (nlHsVar range_RDR) (mkLHsVarTuple [a,b])) @@ -1072,7 +1072,7 @@ gen_Read_binds get_fixity loc tycon data_con_str con = occNameString (getOccName con) read_arg a ty = ASSERT( not (isUnliftedType ty) ) - noLoc (mkBindStmt (nlVarPat a) (nlHsVarApps step_RDR [readPrec_RDR])) + noLoc (mkPsBindStmt (nlVarPat a) (nlHsVarApps step_RDR [readPrec_RDR])) -- When reading field labels we might encounter -- a = 3 @@ -1081,7 +1081,7 @@ gen_Read_binds get_fixity loc tycon -- Note the parens! read_field lbl a = [noLoc - (mkBindStmt + (mkPsBindStmt (nlVarPat a) (nlHsApp read_field ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -364,7 +364,7 @@ tcArrDoStmt env _ (BodyStmt _ rhs _ _) res_ty thing_inside ; thing <- thing_inside res_ty ; return (BodyStmt elt_ty rhs' noSyntaxExpr noSyntaxExpr, thing) } -tcArrDoStmt env ctxt (BindStmt _ pat rhs _ _) res_ty thing_inside +tcArrDoStmt env ctxt (BindStmt _ pat rhs) res_ty thing_inside = do { (rhs', pat_ty) <- tc_arr_rhs env rhs ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ thing_inside res_ty ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -415,7 +415,7 @@ tcGuardStmt _ (BodyStmt _ guard _ _) res_ty thing_inside ; thing <- thing_inside res_ty ; return (BodyStmt boolTy guard' noSyntaxExpr noSyntaxExpr, thing) } -tcGuardStmt ctxt (BindStmt _ pat rhs _ _) res_ty thing_inside +tcGuardStmt ctxt (BindStmt _ pat rhs) res_ty thing_inside = do { (rhs', rhs_ty) <- tcInferRhoNC rhs -- Stmt has a context already ; (pat', thing) <- tcPat_O (StmtCtxt ctxt) (lexprCtOrigin rhs) @@ -449,7 +449,7 @@ tcLcStmt _ _ (LastStmt x body noret _) elt_ty thing_inside ; return (LastStmt x body' noret noSyntaxExpr, thing) } -- A generator, pat <- rhs -tcLcStmt m_tc ctxt (BindStmt _ pat rhs _ _) elt_ty thing_inside +tcLcStmt m_tc ctxt (BindStmt _ pat rhs) elt_ty thing_inside = do { pat_ty <- newFlexiTyVarTy liftedTypeKind ; rhs' <- tcMonoExpr rhs (mkCheckExpType $ mkTyConApp m_tc [pat_ty]) ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ @@ -568,10 +568,10 @@ tcMcStmt _ (LastStmt x body noret return_op) res_ty thing_inside -- q :: a -- -tcMcStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside +tcMcStmt ctxt (BindStmt xbsrn pat rhs) res_ty thing_inside -- (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty = do { ((rhs', pat', thing, new_res_ty), bind_op') - <- tcSyntaxOp MCompOrigin bind_op + <- tcSyntaxOp MCompOrigin (xbsrn_bindOp xbsrn) [SynRho, SynFun SynAny SynRho] res_ty $ \ [rhs_ty, pat_ty, new_res_ty] -> do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) @@ -581,9 +581,15 @@ tcMcStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside ; return (rhs', pat', thing, new_res_ty) } -- If (but only if) the pattern can fail, typecheck the 'fail' operator - ; fail_op' <- tcMonadFailOp (MCompPatOrigin pat) pat' fail_op new_res_ty + ; fail_op' <- fmap join . forM (xbsrn_failOp xbsrn) $ \fail -> + tcMonadFailOp (MCompPatOrigin pat) pat' fail new_res_ty - ; return (BindStmt new_res_ty pat' rhs' bind_op' fail_op', thing) } + ; let xbstc = XBindStmtTc + { xbstc_bindOp = bind_op' + , xbstc_boundResultType = new_res_ty + , xbstc_failOp = fail_op' + } + ; return (BindStmt xbstc pat' rhs', thing) } -- Boolean expressions. -- @@ -825,14 +831,14 @@ tcDoStmt _ (LastStmt x body noret _) res_ty thing_inside ; thing <- thing_inside (panic "tcDoStmt: thing_inside") ; return (LastStmt x body' noret noSyntaxExpr, thing) } -tcDoStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside +tcDoStmt ctxt (BindStmt xbsrn pat rhs) res_ty thing_inside = do { -- Deal with rebindable syntax: -- (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty -- This level of generality is needed for using do-notation -- in full generality; see #1537 ((rhs', pat', new_res_ty, thing), bind_op') - <- tcSyntaxOp DoOrigin bind_op [SynRho, SynFun SynAny SynRho] res_ty $ + <- tcSyntaxOp DoOrigin (xbsrn_bindOp xbsrn) [SynRho, SynFun SynAny SynRho] res_ty $ \ [rhs_ty, pat_ty, new_res_ty] -> do { rhs' <- tcMonoExprNC rhs (mkCheckExpType rhs_ty) ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat @@ -841,9 +847,14 @@ tcDoStmt ctxt (BindStmt _ pat rhs bind_op fail_op) res_ty thing_inside ; return (rhs', pat', new_res_ty, thing) } -- If (but only if) the pattern can fail, typecheck the 'fail' operator - ; fail_op' <- tcMonadFailOp (DoPatOrigin pat) pat' fail_op new_res_ty - - ; return (BindStmt new_res_ty pat' rhs' bind_op' fail_op', thing) } + ; fail_op' <- fmap join . forM (xbsrn_failOp xbsrn) $ \fail -> + tcMonadFailOp (DoPatOrigin pat) pat' fail new_res_ty + ; let xbstc = XBindStmtTc + { xbstc_bindOp = bind_op' + , xbstc_boundResultType = new_res_ty + , xbstc_failOp = fail_op' + } + ; return (BindStmt xbstc pat' rhs', thing) } tcDoStmt ctxt (ApplicativeStmt _ pairs mb_join) res_ty thing_inside = do { let tc_app_stmts ty = tcApplicativeStmts ctxt pairs ty $ @@ -937,16 +948,17 @@ tcMonadFailOp :: CtOrigin -> LPat GhcTcId -> SyntaxExpr GhcRn -- The fail op -> TcType -- Type of the whole do-expression - -> TcRn (SyntaxExpr GhcTcId) -- Typechecked fail op --- Get a 'fail' operator expression, to use if the pattern --- match fails. If the pattern is irrefutatable, just return --- noSyntaxExpr; it won't be used + -> TcRn (FailOperator GhcTcId) -- Typechecked fail op +-- Get a 'fail' operator expression, to use if the pattern match fails. +-- This won't be used in cases where we've already determined the pattern +-- match can't fail (so the fail op is Nothing), however, it seems that the +-- isIrrefutableHsPat test is still required here for some reason I haven't +-- yet determined. tcMonadFailOp orig pat fail_op res_ty | isIrrefutableHsPat pat - = return noSyntaxExpr - + = return Nothing | otherwise - = snd <$> (tcSyntaxOp orig fail_op [synKnownType stringTy] + = Just . snd <$> (tcSyntaxOp orig fail_op [synKnownType stringTy] (mkCheckExpType res_ty) $ \_ -> return ()) {- @@ -1025,22 +1037,23 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside -> TcM (ApplicativeArg GhcTcId) goArg body_ty (ApplicativeArgOne - { app_arg_pattern = pat - , arg_expr = rhs - , fail_operator = fail_op + { xarg_app_arg_one = fail_op + , app_arg_pattern = pat + , arg_expr = rhs , .. }, pat_ty, exp_ty) = setSrcSpan (combineSrcSpans (getLoc pat) (getLoc rhs)) $ - addErrCtxt (pprStmtInCtxt ctxt (mkBindStmt pat rhs)) $ + addErrCtxt (pprStmtInCtxt ctxt (mkRnBindStmt pat rhs)) $ do { rhs' <- tcMonoExprNC rhs (mkCheckExpType exp_ty) ; (pat', _) <- tcPat (StmtCtxt ctxt) pat (mkCheckExpType pat_ty) $ return () - ; fail_op' <- tcMonadFailOp (DoPatOrigin pat) pat' fail_op body_ty + ; fail_op' <- fmap join . forM fail_op $ \fail -> + tcMonadFailOp (DoPatOrigin pat) pat' fail body_ty ; return (ApplicativeArgOne - { app_arg_pattern = pat' + { xarg_app_arg_one = fail_op' + , app_arg_pattern = pat' , arg_expr = rhs' - , fail_operator = fail_op' , .. } ) } ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2193,11 +2193,13 @@ tcUserStmt (L loc (BodyStmt _ expr _ _)) (NValBinds [(NonRecursive,unitBag the_bind)] []) -- [it <- e] - bind_stmt = L loc $ BindStmt noExtField + bind_stmt = L loc $ BindStmt + (XBindStmtRn + { xbsrn_bindOp = mkRnSyntaxExpr bindIOName + , xbsrn_failOp = Nothing + }) (L loc (VarPat noExtField (L loc fresh_it))) (nlHsApp ghciStep rn_expr) - (mkRnSyntaxExpr bindIOName) - noSyntaxExpr -- [; print it] print_it = L loc $ BodyStmt noExtField @@ -2327,8 +2329,8 @@ tcUserStmt rdr_stmt@(L loc _) ; ghciStep <- getGhciStepIO ; let gi_stmt - | (L loc (BindStmt ty pat expr op1 op2)) <- rn_stmt - = L loc $ BindStmt ty pat (nlHsApp ghciStep expr) op1 op2 + | (L loc (BindStmt x pat expr)) <- rn_stmt + = L loc $ BindStmt x pat (nlHsApp ghciStep expr) | otherwise = rn_stmt ; opt_pr_flag <- goptM Opt_PrintBindResult ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -1190,14 +1190,21 @@ zonkStmt env _ (LetStmt x (L l binds)) = do (env1, new_binds) <- zonkLocalBinds env binds return (env1, LetStmt x (L l new_binds)) -zonkStmt env zBody (BindStmt bind_ty pat body bind_op fail_op) - = do { (env1, new_bind) <- zonkSyntaxExpr env bind_op - ; new_bind_ty <- zonkTcTypeToTypeX env1 bind_ty +zonkStmt env zBody (BindStmt xbs pat body) + = do { (env1, new_bind) <- zonkSyntaxExpr env (xbstc_bindOp xbs) + ; new_bind_ty <- zonkTcTypeToTypeX env1 (xbstc_boundResultType xbs) ; new_body <- zBody env1 body ; (env2, new_pat) <- zonkPat env1 pat - ; (_, new_fail) <- zonkSyntaxExpr env1 fail_op + ; new_fail <- case xbstc_failOp xbs of + Nothing -> return Nothing + Just f -> fmap (Just . snd) (zonkSyntaxExpr env1 f) ; return ( env2 - , BindStmt new_bind_ty new_pat new_body new_bind new_fail) } + , BindStmt (XBindStmtTc + { xbstc_bindOp = new_bind + , xbstc_boundResultType = new_bind_ty + , xbstc_failOp = new_fail + }) + new_pat new_body) } -- Scopes: join > ops (in reverse order) > pats (in forward order) -- > rest of stmts @@ -1212,14 +1219,14 @@ zonkStmt env _zBody (ApplicativeStmt body_ty args mb_join) zonk_join env (Just j) = second Just <$> zonkSyntaxExpr env j get_pat :: (SyntaxExpr GhcTcId, ApplicativeArg GhcTcId) -> LPat GhcTcId - get_pat (_, ApplicativeArgOne _ pat _ _ _) = pat + get_pat (_, ApplicativeArgOne _ pat _ _) = pat get_pat (_, ApplicativeArgMany _ _ _ pat) = pat replace_pat :: LPat GhcTcId -> (SyntaxExpr GhcTc, ApplicativeArg GhcTc) -> (SyntaxExpr GhcTc, ApplicativeArg GhcTc) - replace_pat pat (op, ApplicativeArgOne x _ a isBody fail_op) - = (op, ApplicativeArgOne x pat a isBody fail_op) + replace_pat pat (op, ApplicativeArgOne fail_op _ a isBody) + = (op, ApplicativeArgOne fail_op pat a isBody) replace_pat pat (op, ApplicativeArgMany x a b _) = (op, ApplicativeArgMany x a b pat) @@ -1239,10 +1246,13 @@ zonkStmt env _zBody (ApplicativeStmt body_ty args mb_join) ; return (env2, (new_op, new_arg) : new_args) } zonk_args_rev env [] = return (env, []) - zonk_arg env (ApplicativeArgOne x pat expr isBody fail_op) + zonk_arg env (ApplicativeArgOne fail_op pat expr isBody) = do { new_expr <- zonkLExpr env expr - ; (_, new_fail) <- zonkSyntaxExpr env fail_op - ; return (ApplicativeArgOne x pat new_expr isBody new_fail) } + ; new_fail <- forM fail_op $ \old_fail -> + do { (_, fail') <- zonkSyntaxExpr env old_fail + ; return fail' + } + ; return (ApplicativeArgOne new_fail pat new_expr isBody) } zonk_arg env (ApplicativeArgMany x stmts ret pat) = do { (env1, new_stmts) <- zonkStmts env zonkLExpr stmts ; new_ret <- zonkExpr env1 ret ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1147,7 +1147,7 @@ cvtStmts = mapM cvtStmt cvtStmt :: TH.Stmt -> CvtM (Hs.LStmt GhcPs (LHsExpr GhcPs)) cvtStmt (NoBindS e) = do { e' <- cvtl e; returnL $ mkBodyStmt e' } -cvtStmt (TH.BindS p e) = do { p' <- cvtPat p; e' <- cvtl e; returnL $ mkBindStmt p' e' } +cvtStmt (TH.BindS p e) = do { p' <- cvtPat p; e' <- cvtl e; returnL $ mkPsBindStmt p' e' } cvtStmt (TH.LetS ds) = do { ds' <- cvtLocalDecs (text "a let binding") ds ; returnL $ LetStmt noExtField (noLoc ds') } cvtStmt (TH.ParS dss) = do { dss' <- mapM cvt_one dss ===================================== compiler/parser/Parser.y ===================================== @@ -3292,7 +3292,7 @@ stmt :: { forall b. DisambECP b => PV (LStmt GhcPs (Located b)) } qual :: { forall b. DisambECP b => PV (LStmt GhcPs (Located b)) } : bindpat '<-' exp { runECP_PV $3 >>= \ $3 -> - ams (sLL $1 $> $ mkBindStmt $1 $3) + ams (sLL $1 $> $ mkPsBindStmt $1 $3) [mu AnnLarrow $2] } | exp { runECP_PV $1 >>= \ $1 -> return $ sL1 $1 $ mkBodyStmt $1 } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bfde3b76ac7f5a72eca012fe34ac1340a5ce2011...18bc16ed78dfa1fe9498c5ac1ca38e9f84267872 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bfde3b76ac7f5a72eca012fe34ac1340a5ce2011...18bc16ed78dfa1fe9498c5ac1ca38e9f84267872 You're receiving 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 18 17:20:39 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 13:20:39 -0400 Subject: [Git][ghc/ghc][master] Add a missing zonk in tcHsPartialType Message-ID: <5e9b36e771b9d_616765c7a28561431a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 4 changed files: - compiler/GHC/Tc/Gen/HsType.hs - + testsuite/tests/partial-sigs/should_compile/T18008.hs - + testsuite/tests/partial-sigs/should_compile/T18008.stderr - testsuite/tests/partial-sigs/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -732,6 +732,7 @@ tc_hs_type mode forall@(HsForAllTy { hst_fvf = fvf, hst_bndrs = hs_tvs m_telescope = Just (sep (map ppr hs_tvs)) ; emitResidualTvConstraint skol_info m_telescope tvs' tclvl wanted + -- See Note [Skolem escape and forall-types] ; return (mkForAllTys bndrs ty') } @@ -920,6 +921,26 @@ under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types +Note [Skolem escape and forall-types] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + f :: forall a. (forall kb (b :: kb). Proxy '[a, b]) -> () + +The Proxy '[a,b] forces a and b to have the same kind. But a's +kind must be bound outside the 'forall a', and hence escapes. +We discover this by building an implication constraint for +each forall. So the inner implication constraint will look like + forall kb (b::kb). kb ~ ka +where ka is a's kind. We can't unify these two, /even/ if ka is +unification variable, because it would be untouchable inside +this inner implication. + +That's what the pushLevelAndCaptureConstraints, plus subsequent +emitResidualTvConstraint is all about, when kind-checking +HsForAllTy. + +Note that we don't need to /simplify/ the constraints here +because we aren't generalising. We just capture them. -} {- ********************************************************************* @@ -2819,10 +2840,13 @@ kindGeneralizeAll ty = do { traceTc "kindGeneralizeAll" empty ; kindGeneralizeSome (const True) ty } -- | Specialized version of 'kindGeneralizeSome', but where no variables --- can be generalized. Use this variant when it is unknowable whether metavariables --- might later be constrained. --- See Note [Recipe for checking a signature] for why and where this --- function is needed. +-- can be generalized, but perhaps some may neeed to be promoted. +-- Use this variant when it is unknowable whether metavariables might +-- later be constrained. +-- +-- To see why this promotion is needed, see +-- Note [Recipe for checking a signature], and especially +-- Note [Promotion in signatures]. kindGeneralizeNone :: TcType -- needn't be zonked -> TcM () kindGeneralizeNone ty @@ -3160,7 +3184,7 @@ tcHsPartialSigType ctxt sig_ty ; return (wcs, wcx, theta, tau) } - -- No kind-generalization here: + -- No kind-generalization here, but perhaps some promotion ; kindGeneralizeNone (mkSpecForAllTys implicit_tvs $ mkSpecForAllTys explicit_tvs $ mkPhiTy theta $ @@ -3171,6 +3195,14 @@ tcHsPartialSigType ctxt sig_ty -- See Note [Extra-constraint holes in partial type signatures] ; emitNamedWildCardHoleConstraints wcs + -- Zonk, so that any nested foralls can "see" their occurrences + -- See Note [Checking partial type signatures], in + -- the bullet on Nested foralls. + ; implicit_tvs <- mapM zonkTcTyVarToTyVar implicit_tvs + ; explicit_tvs <- mapM zonkTcTyVarToTyVar explicit_tvs + ; theta <- mapM zonkTcType theta + ; tau <- zonkTcType tau + -- We return a proper (Name,TyVar) environment, to be sure that -- we bring the right name into scope in the function body. -- Test case: partial-sigs/should_compile/LocalDefinitionBug @@ -3179,7 +3211,7 @@ tcHsPartialSigType ctxt sig_ty -- NB: checkValidType on the final inferred type will be -- done later by checkInferredPolyId. We can't do it - -- here because we don't have a complete tuype to check + -- here because we don't have a complete type to check ; traceTc "tcHsPartialSigType" (ppr tv_prs) ; return (wcs, wcx, tv_prs, theta, tau) } @@ -3198,12 +3230,31 @@ tcPartialContext hs_theta {- Note [Checking partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See also Note [Recipe for checking a signature] +This Note is about tcHsPartialSigType. See also +Note [Recipe for checking a signature] When we have a partial signature like - f,g :: forall a. a -> _ + f :: forall a. a -> _ we do the following +* tcHsPartialSigType does not make quantified type (forall a. blah) + and then instantiate it -- it makes no sense to instantiate a type + with wildcards in it. Rather, tcHsPartialSigType just returns the + 'a' and the 'blah' separately. + + Nor, for the same reason, do we push a level in tcHsPartialSigType. + +* We instantiate 'a' to a unification variable, a TyVarTv, and /not/ + a skolem; hence the "_Tv" in bindExplicitTKBndrs_Tv. Consider + f :: forall a. a -> _ + g :: forall b. _ -> b + f = g + g = f + They are typechecked as a recursive group, with monomorphic types, + so 'a' and 'b' will get unified together. Very like kind inference + for mutually recursive data types (sans CUSKs or SAKS); see + Note [Cloning for tyvar binders] in GHC.Tc.Gen.HsType + * In GHC.Tc.Gen.Sig.tcUserSigType we return a PartialSig, which (unlike the companion CompleteSig) contains the original, as-yet-unchecked source-code LHsSigWcType @@ -3218,12 +3269,28 @@ we do the following g x = True It's really as if we'd written two distinct signatures. -* Note that we don't make quantified type (forall a. blah) and then - instantiate it -- it makes no sense to instantiate a type with - wildcards in it. Rather, tcHsPartialSigType just returns the - 'a' and the 'blah' separately. - - Nor, for the same reason, do we push a level in tcHsPartialSigType. +* Nested foralls. Consider + f :: forall b. (forall a. a -> _) -> b + We do /not/ allow the "_" to be instantiated to 'a'; but we do + (as before) allow it to be instantiated to the (top level) 'b'. + Why not? Because suppose + f x = (x True, x 'c') + We must instantiate that (forall a. a -> _) when typechecking + f's body, so we must know precisely where all the a's are; they + must not be hidden under (filled-in) unification variables! + + We achieve this in the usual way: we push a level at a forall, + so now the unification variable for the "_" can't unify with + 'a'. + +* Just as for ordinary signatures, we must zonk the type after + kind-checking it, to ensure that all the nested forall binders can + see their occurrenceds + + Just as for ordinary signatures, this zonk also gets any Refl casts + out of the way of instantiation. Example: #18008 had + foo :: (forall a. (Show a => blah) |> Refl) -> _ + and that Refl cast messed things up. See #18062. Note [Extra-constraint holes in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== testsuite/tests/partial-sigs/should_compile/T18008.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE PartialTypeSignatures #-} +module Bug where + +f :: (forall a. Show a => a -> String) -> _ +f s = s () + ===================================== testsuite/tests/partial-sigs/should_compile/T18008.stderr ===================================== @@ -0,0 +1,5 @@ + +T18008.hs:5:43: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_’ standing for ‘String’ + • In the type ‘(forall a. Show a => a -> String) -> _’ + In the type signature: f :: (forall a. Show a => a -> String) -> _ ===================================== testsuite/tests/partial-sigs/should_compile/all.T ===================================== @@ -95,3 +95,4 @@ test('T16334', normal, compile, ['']) test('T16728', normal, compile, ['']) test('T16728a', normal, compile, ['']) test('T16728b', normal, compile, ['']) +test('T18008', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84cc8394d075cea236faa0bcd9ef0a84de89ee8c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84cc8394d075cea236faa0bcd9ef0a84de89ee8c You're receiving 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 18 17:21:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 13:21:15 -0400 Subject: [Git][ghc/ghc][master] 4 commits: gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 Message-ID: <5e9b370b30bc3_616713503ee056175dd@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 3 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - utils/hsc2hs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -26,19 +26,18 @@ stages: - testing # head.hackage correctness and compiler performance testing - deploy # push documentation -# N.B.Don't run on wip/ branches, instead on run on merge requests. -.only-default: &only-default - only: - - master - - /ghc-[0-9]+\.[0-9]+/ - - merge_requests - - tags - - web +workflow: + # N.B.Don't run on wip/ branches, instead on run on merge requests. + rules: + - if: $CI_MERGE_REQUEST_ID + - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' + - if: '$CI_PIPELINE_SOURCE == "web"' .nightly: &nightly - only: - variables: - - $NIGHTLY + rules: + - if: $NIGHTLY artifacts: when: always expire_in: 8 weeks @@ -50,9 +49,8 @@ stages: artifacts: when: always expire_in: 1 year - only: - variables: - - $RELEASE == "yes" + rules: + - if: '$RELEASE == "yes"' ############################################################ # Runner Tags @@ -86,13 +84,11 @@ ghc-linters: dependencies: [] tags: - lint - only: - refs: - - merge_requests + rules: + - if: $CI_MERGE_REQUEST_ID # Run mypy Python typechecker on linter scripts. lint-linters: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -103,7 +99,6 @@ lint-linters: # Check that .T files all parse by listing broken tests. lint-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" script: @@ -114,7 +109,6 @@ lint-testsuite: # Run mypy Python typechecker on testsuite driver typecheck-testsuite: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -127,7 +121,6 @@ typecheck-testsuite: # accommodate, e.g., haddock changes not yet upstream) but not on `master` or # Marge jobs. .lint-submods: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" script: @@ -140,25 +133,14 @@ typecheck-testsuite: tags: - lint -lint-submods-marge: +lint-submods: extends: .lint-submods - only: - refs: - - merge_requests - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" - -lint-submods-mr: - extends: .lint-submods - # Allow failure since any necessary submodule patches may not be upstreamed - # yet. - allow_failure: true - only: - refs: - - merge_requests - except: - variables: - - "$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/" + # Allow failure on merge requests since any necessary submodule patches may + # not be upstreamed yet. + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' + allow_failure: false + - allow_failure: true lint-submods-branch: extends: .lint-submods @@ -166,13 +148,11 @@ lint-submods-branch: - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - git submodule foreach git remote update - submodchecker . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) - only: - refs: - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' .lint-changelogs: - <<: *only-default stage: lint image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" dependencies: [] @@ -185,15 +165,13 @@ lint-changelogs: extends: .lint-changelogs # Allow failure since this isn't a final release. allow_failure: true - only: - refs: - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' lint-release-changelogs: extends: .lint-changelogs - only: - refs: - - /ghc-[0-9]+\.[0-9]+\.[0-9]+-.*/ + rules: + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' ############################################################ @@ -201,7 +179,6 @@ lint-release-changelogs: ############################################################ .validate-hadrian: - <<: *only-default variables: FLAVOUR: "validate" script: @@ -250,7 +227,6 @@ validate-x86_64-linux-deb9-unreg-hadrian: TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" hadrian-ghc-in-ghci: - <<: *only-default stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" before_script: @@ -283,7 +259,6 @@ hadrian-ghc-in-ghci: ############################################################ .validate: - <<: *only-default variables: TEST_TYPE: test MAKE_ARGS: "-Werror" @@ -317,8 +292,8 @@ hadrian-ghc-in-ghci: # porting guide [1]. # [1] https://www.freebsd.org/doc/en/books/porters-handbook/using-iconv.html) 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" - GHC_VERSION: 8.6.3 - CABAL_INSTALL_VERSION: 3.0.0.0 + GHC_VERSION: 8.10.1 + CABAL_INSTALL_VERSION: 3.2.0.0 BIN_DIST_PREP_TAR_COMP: "ghc-x86_64-portbld-freebsd.tar.xz" TEST_ENV: "x86_64-freebsd" BUILD_FLAVOUR: "validate" @@ -334,10 +309,12 @@ hadrian-ghc-in-ghci: - cabal-cache - toolchain -# Disabled due to lack of builder capacity -.validate-x86_64-freebsd: +# Conditional due to lack of builder capacity +validate-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/' nightly-x86_64-freebsd: <<: *nightly @@ -414,7 +391,6 @@ validate-x86_64-darwin: # Disabled because of OS X CI capacity .validate-x86_64-darwin-hadrian: - <<: *only-default stage: full-build tags: - x86_64-darwin @@ -777,7 +753,6 @@ validate-x86_64-linux-fedora27: ############################################################ .build-windows: - <<: *only-default # For the reasons given in #17777 this build isn't reliable. allow_failure: true before_script: @@ -951,7 +926,6 @@ nightly-i386-windows: # See Note [Cleanup after shell executor] cleanup-darwin: - <<: *only-default stage: cleanup tags: - x86_64-darwin @@ -973,7 +947,6 @@ cleanup-darwin: ############################################################ doc-tarball: - <<: *only-default stage: packaging tags: - x86_64-linux @@ -1013,10 +986,10 @@ source-tarball: tags: - x86_64-linux image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - when: always dependencies: [] - only: - - tags + rules: + - if: $CI_COMMIT_TAG + when: always artifacts: paths: - ghc-*.tar.xz @@ -1043,7 +1016,6 @@ source-tarball: # pipeline. .hackage: - <<: *only-default stage: testing image: ghcci/x86_64-linux-deb9:0.2 tags: @@ -1060,9 +1032,8 @@ hackage: hackage-label: extends: .hackage - only: - variables: - - $CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/ + rules: + - if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' nightly-hackage: <<: *nightly @@ -1077,11 +1048,10 @@ perf-nofib: dependencies: - validate-x86_64-linux-deb9-dwarf image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - only: - refs: - - merge_requests - - master - - /ghc-[0-9]+\.[0-9]+/ + rules: + - if: $CI_MERGE_REQUEST_ID + - if: '$CI_COMMIT_BRANCH == "master"' + - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' tags: - x86_64-linux script: @@ -1130,8 +1100,8 @@ pages: EOF - cp -f index.html public/doc - only: - - master + rules: + - if: '$CI_COMMIT_BRANCH == "master"' artifacts: paths: - public ===================================== .gitlab/ci.sh ===================================== @@ -139,12 +139,6 @@ function set_toolchain_paths() { export CABAL export HAPPY export ALEX - - # FIXME: Temporarily use ghc from ports - case "$(uname)" in - FreeBSD) GHC="/usr/local/bin/ghc" ;; - *) ;; - esac } # Extract GHC toolchain ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit dff4ed1acf9ebbdd004fc833a474dc8c16a90f5b +Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/84cc8394d075cea236faa0bcd9ef0a84de89ee8c...e2586828a30202a28dcacac9ab7fc83c43da9e02 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/84cc8394d075cea236faa0bcd9ef0a84de89ee8c...e2586828a30202a28dcacac9ab7fc83c43da9e02 You're receiving 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 18 17:21:53 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 13:21:53 -0400 Subject: [Git][ghc/ghc][master] Improve prepForeignCall error reporting Message-ID: <5e9b373151bea_616713503ee056205e2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 1 changed file: - libraries/ghci/GHCi/FFI.hsc Changes: ===================================== libraries/ghci/GHCi/FFI.hsc ===================================== @@ -58,15 +58,29 @@ prepForeignCall cconv arg_types result_type = do cif <- mallocBytes (#const sizeof(ffi_cif)) let abi = convToABI cconv r <- ffi_prep_cif cif abi (fromIntegral n_args) (ffiType result_type) arg_arr - if (r /= fFI_OK) - then throwIO (ErrorCall ("prepForeignCallFailed: " ++ show r)) - else return (castPtr cif) + if r /= fFI_OK then + throwIO $ ErrorCall $ concat + [ "prepForeignCallFailed: ", strError r, + "(cconv: ", show cconv, + " arg tys: ", show arg_types, + " res ty: ", show result_type, ")" ] + else + return (castPtr cif) freeForeignCallInfo :: Ptr C_ffi_cif -> IO () freeForeignCallInfo p = do free ((#ptr ffi_cif, arg_types) p) free p +strError :: C_ffi_status -> String +strError r + | r == fFI_BAD_ABI + = "invalid ABI (FFI_BAD_ABI)" + | r == fFI_BAD_TYPEDEF + = "invalid type description (FFI_BAD_TYPEDEF)" + | otherwise + = "unknown error: " ++ show r + convToABI :: FFIConv -> C_ffi_abi convToABI FFICCall = fFI_DEFAULT_ABI #if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH) @@ -108,12 +122,10 @@ foreign import ccall "&ffi_type_float" ffi_type_float :: Ptr C_ffi_type foreign import ccall "&ffi_type_double" ffi_type_double :: Ptr C_ffi_type foreign import ccall "&ffi_type_pointer"ffi_type_pointer :: Ptr C_ffi_type -fFI_OK :: C_ffi_status -fFI_OK = (#const FFI_OK) ---fFI_BAD_ABI :: C_ffi_status ---fFI_BAD_ABI = (#const FFI_BAD_ABI) ---fFI_BAD_TYPEDEF :: C_ffi_status ---fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF) +fFI_OK, fFI_BAD_ABI, fFI_BAD_TYPEDEF :: C_ffi_status +fFI_OK = (#const FFI_OK) +fFI_BAD_ABI = (#const FFI_BAD_ABI) +fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF) fFI_DEFAULT_ABI :: C_ffi_abi fFI_DEFAULT_ABI = (#const FFI_DEFAULT_ABI) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15ab6cd548f284732a7f89d78c2b89b1bfc4ea1d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/15ab6cd548f284732a7f89d78c2b89b1bfc4ea1d You're receiving 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 18 17:27:14 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 18 Apr 2020 13:27:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18055 Message-ID: <5e9b3872be87a_61673f81ef22dee4562075e@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18055 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18055 You're receiving 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 18 18:56:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 18 Apr 2020 14:56:22 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 9 commits: XXX: Tracing Message-ID: <5e9b4d56dbf2b_61673f8198ee100c56351b5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 12decb2a by Ben Gamari at 2020-04-17T20:17:18+00:00 XXX: Tracing - - - - - 9710994c by Ben Gamari at 2020-04-18T02:02:09+00:00 Fix CoreLint - - - - - 3c0f3eaf by Ben Gamari at 2020-04-18T02:02:28+00:00 XXX: Eta expand This shouldn't be necessary - - - - - f0c45959 by Ben Gamari at 2020-04-18T03:27:47+00:00 lintJoinLams look through casts - - - - - 1758b5eb by Ben Gamari at 2020-04-18T03:29:25+00:00 XXX: CoreLint: Relax tail call restriction on join points - - - - - c8f5b207 by Ben Gamari at 2020-04-18T17:10:25+00:00 Remove state token from keepAlive# - - - - - dc538a69 by Ben Gamari at 2020-04-18T17:10:42+00:00 Desugar: Eta expand runRW# continuation - - - - - 98621772 by Ben Gamari at 2020-04-18T17:11:05+00:00 XXX: Don't apply Note [dodgy unsafeCoerce 1] - - - - - ae6dae6a by Ben Gamari at 2020-04-18T17:22:32+00:00 CorePrep: Catch unexpected runRW# applications - - - - - 15 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/Simplify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Types/Id/Make.hs - compiler/prelude/primops.txt.pp - libraries/base/Foreign/Marshal/Alloc.hs - libraries/base/GHC/ForeignPtr.hs - libraries/base/GHC/IO/Unsafe.hs - libraries/base/GHC/ST.hs - libraries/ghc-compact/GHC/Compact/Serialized.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -708,8 +708,13 @@ lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM LintedType lintJoinLams join_arity enforce rhs = go join_arity rhs where - go 0 rhs = lintCoreExpr rhs - go n (Lam var expr) = lintLambda var $ go (n-1) expr + go 0 rhs = lintCoreExpr rhs + go n (Lam var expr) = lintLambda var $ go (n-1) expr + go n (Cast expr co) = do { _ <- go n expr + ; lintCastExpr expr co + } + -- N.B. join points can be cast. e.g. we consider ((\x -> ...) `cast` ...) + -- to be a join point at join arity 1. go n _other | Just bndr <- enforce -- Join point with too few RHS lambdas = failWithL $ mkBadJoinArityMsg bndr join_arity n rhs | otherwise -- Future join point, not yet eta-expanded @@ -770,6 +775,19 @@ type LintedCoercion = Coercion type LintedTyCoVar = TyCoVar type LintedId = Id +-- | Lint an expression cast through the given coercion, returning the type +-- resulting from the cast. +lintCastExpr :: CoreExpr -> Coercion -> LintM LintedType +lintCastExpr expr co + = do { expr_ty <- markAllJoinsBad $ lintCoreExpr expr + ; co' <- lintCoercion co + ; let (Pair from_ty to_ty, role) = coercionKindRole co' + ; checkValueType to_ty $ + text "target of cast" <+> quotes (ppr co') + ; lintRole co' Representational role + ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) + ; return to_ty } + lintCoreExpr :: CoreExpr -> LintM LintedType -- The returned type has the substitution from the monad -- already applied to it: @@ -787,14 +805,7 @@ lintCoreExpr (Lit lit) = return (literalType lit) lintCoreExpr (Cast expr co) - = do { expr_ty <- markAllJoinsBad $ lintCoreExpr expr - ; co' <- lintCoercion co - ; let (Pair from_ty to_ty, role) = coercionKindRole co' - ; checkValueType to_ty $ - text "target of cast" <+> quotes (ppr co') - ; lintRole co' Representational role - ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) - ; return to_ty } + = markAllJoinsBad $ lintCastExpr expr co lintCoreExpr (Tick tickish expr) = do case tickish of @@ -863,14 +874,23 @@ lintCoreExpr e@(App _ _) ; arg3_ty <- lintJoinLams 1 (Just fun) arg3 ; lintValApp arg3 fun_ty2 arg3_ty } + | Var fun <- fun + , fun `hasKey` runRWKey + = failWithL (text "Invalid runRW# application") + | Var fun <- fun , fun `hasKey` keepAliveIdKey - , [arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5, arg6, arg7] <- args - = do { fun_ty5 <- lintCoreArgs (idType fun) [ arg_ty1, arg_ty2, arg_ty3, arg_ty4 ] - ; arg6_ty <- lintJoinLams 1 (Just fun) arg6 -- f :: State# RW -> (# State# RW, o #) - ; lintCoreArgs fun_ty5 [arg5, arg6, arg7] + , [arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5, arg6] <- args + = do { fun_ty6 <- lintCoreArgs (idType fun) + [ arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5 ] + ; arg6_ty <- lintJoinLams 0 (Just fun) arg6 -- f :: State# RW -> (# State# RW, o #) + ; lintValApp arg6 fun_ty6 arg6_ty } + | Var fun <- fun + , fun `hasKey` keepAliveIdKey + = failWithL (text "Invalid keepAlive# application") + | otherwise = do { fun_ty <- lintCoreFun fun (length args) ; lintCoreArgs fun_ty args } @@ -1172,9 +1192,7 @@ lintCaseExpr scrut var alt_ty alts = do { let e = Case scrut var alt_ty alts -- Just for error messages -- Check the scrutinee - ; scrut_ty <- markAllJoinsBad $ lintCoreExpr scrut - -- See Note [Join points are less general than the paper] - -- in GHC.Core + ; scrut_ty <- lintCoreExpr scrut ; alt_ty <- addLoc (CaseTy scrut) $ lintValueType alt_ty ===================================== compiler/GHC/Core/Op/Simplify.hs ===================================== @@ -1897,27 +1897,29 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont | fun `hasKey` keepAliveIdKey - , [ ValArg s0 - , ValArg (Lam f_arg f_body) + , [ ValArg y , ValArg x , TyArg {} -- res_ty , TyArg {} -- res_rep , TyArg {as_arg_ty=arg_ty} , TyArg {as_arg_ty=arg_rep} ] <- rev_args - -- Extract type of second component of (# State# RealWorld, a #) - , Just (_, [_, _, _, ty']) <- splitTyConApp_maybe (contResultType cont) - = do { (env', f_arg) <- simplLamBndr (zapSubstEnv env) f_arg - ; f_body' <- simplExprC env' f_body cont - ; let f' = Lam f_arg f_body' + = do { let ty' = contResultType cont + ; j <- newJoinId [] ty' + ; let env' = zapSubstEnv env + ; y' <- simplExprC env' y cont + ; let bind = NonRec j y' + ; x' <- simplExpr env' x + ; arg_rep' <- simplType env' arg_rep + ; arg_ty' <- simplType env' arg_ty ; let call' = mkApps (Var fun) - [ mkTyArg arg_rep, mkTyArg arg_ty + [ mkTyArg arg_rep', mkTyArg arg_ty' , mkTyArg (getRuntimeRep ty'), mkTyArg ty' - , x - , f' - , s0 + , x' + , Var j ] - ; return (emptyFloats env, call') } + ; --pprTrace "rebuild keepAlive" (ppr fun $$ ppr rev_args $$ ppr cont) $ + return (emptyFloats env `extendFloats` bind, call') } ---------- Simplify applications and casts -------------- rebuildCall env info (CastIt co cont) ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -45,7 +45,7 @@ import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Id.Info import TysWiredIn -import TysPrim ( realWorldStatePrimTy, primRepToRuntimeRep ) +import TysPrim ( realWorldStatePrimTy ) import GHC.Core.DataCon import GHC.Types.Basic import GHC.Types.Module @@ -856,42 +856,26 @@ cpeApp top_env expr Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body [] 0 _ -> cpe_app env arg [CpeApp (Var realWorldPrimId)] 1 + cpe_app env (Var f) args n + | f `hasKey` runRWKey + = pprPanic "cpe_app(runRW#)" (ppr args $$ ppr n) + -- See Note [CorePrep handling of keepAlive#] cpe_app env (Var f) [CpeApp (Type arg_rep), CpeApp (Type arg_ty), - CpeApp (Type result_rep), CpeApp (Type result_ty), - CpeApp x, CpeApp k, CpeApp s0] 3 + CpeApp (Type _result_rep), CpeApp (Type result_ty), + CpeApp x, CpeApp y] 2 | f `hasKey` keepAliveIdKey - = do { let voidRepTy = primRepToRuntimeRep VoidRep - -- out_ty ~ (# State# RealWorld, a #) - out_ty = mkTyConApp (tupleTyCon Unboxed 2) - [voidRepTy, result_rep, realWorldStatePrimTy, result_ty] - ; b0 <- newVar out_ty - ; y <- newVar result_ty - ; s1 <- newVar realWorldStatePrimTy + = do { y' <- newVar result_ty ; s2 <- newVar realWorldStatePrimTy - -- Beta reduce - ; (floats0, k') <- case k of - Lam s body -> cpe_app (extendCorePrepEnvExpr env s s0) body [] 0 - _ -> cpe_app env k [CpeApp s0] 1 ; let touchId = mkPrimOpId TouchOp - - -- @stateResultAlt s y expr@ is a case alternative of the form, - -- (# s, y #) -> expr - stateResultAlt :: Var -> Var -> CoreExpr -> CoreAlt - stateResultAlt stateVar resultVar rhs = - (DataAlt (tupleDataCon Unboxed 2), [stateVar, resultVar], rhs) - - expr = Case k' b0 out_ty [stateResultAlt s1 y rhs1] - rhs1 = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, x, Var s1] - in Case scrut s2 out_ty [(DEFAULT, [], rhs2)] - rhs2 = mkApps (Var $ dataConWrapId $ tupleDataCon Unboxed 2) - [mkTyArg voidRepTy, mkTyArg result_rep, mkTyArg realWorldStatePrimTy, mkTyArg result_ty, Var s2, Var y] - ; (floats1, body) <- pprTrace "cpe_app" (ppr expr) $ cpeBody env expr - ; return (floats0 `appendFloats` floats1, body) + expr = Case y y' result_ty [(DEFAULT, [], rhs1)] + rhs1 = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, x, Var realWorldPrimId] + in Case scrut s2 result_ty [(DEFAULT, [], Var y')] + ; pprTrace "cpe_app" (ppr expr) $ cpeBody env expr } - cpe_app _env (Var f) args _ + cpe_app _env (Var f) args n | f `hasKey` keepAliveIdKey - = pprPanic "cpe_app(keepAlive#)" (ppr args) + = pprPanic "cpe_app(keepAlive#)" (ppr args $$ ppr n) cpe_app env (Var v) args depth = do { v1 <- fiddleCCall v ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -56,6 +56,7 @@ import GHC.Core import GHC.HsToCore.Monad import GHC.Core.Utils +import GHC.Core.Arity ( etaExpand ) import GHC.Core.Make import GHC.Types.Id.Make import GHC.Types.Id @@ -489,6 +490,9 @@ mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg Var v1 | isInternalName (idName v1) -> v1 -- Note [Desugaring seq], points (2) and (3) _ -> mkWildValBinder ty1 +mkCoreAppDs _ e@(Var f `App` Type r `App` Type ty1) arg + | f `hasKey` runRWKey + = e `App` etaExpand 1 arg mkCoreAppDs s fun arg = mkCoreApp s fun arg -- The rest is done in GHC.Core.Make ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -500,7 +500,8 @@ closureCodeBody top_lvl bndr cl_info cc args arity body fv_details (CmmMachOp (mo_wordSub platform) [ CmmReg (CmmLocal node) -- See [NodeReg clobbered with loopification] , mkIntExpr platform (funTag dflags cl_info) ]) - ; fv_bindings <- mapM bind_fv fv_details + ; fv_bindings <- pprTrace "closureBodyBody" (ppr bndr $$ ppr body) + $ mapM bind_fv fv_details -- Load free vars out of closure *after* -- heap check, to reduce live vars over check ; when node_points $ load_fvs node lf_info fv_bindings @@ -523,7 +524,7 @@ closureCodeBody top_lvl bndr cl_info cc args arity body fv_details -- A function closure pointer may be tagged, so we -- must take it into account when accessing the free variables. -bind_fv :: (NonVoid Id, ByteOff) -> FCode (LocalReg, ByteOff) +bind_fv :: HasCallStack => (NonVoid Id, ByteOff) -> FCode (LocalReg, ByteOff) bind_fv (id, off) = do { reg <- rebindToReg id; return (reg, off) } load_fvs :: LocalReg -> LambdaFormInfo -> [(LocalReg, ByteOff)] -> FCode () ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -232,6 +232,13 @@ data LambdaFormInfo | LFLetNoEscape -- See LetNoEscape module for precise description +instance Outputable LambdaFormInfo where + ppr LFReEntrant{} = text "re-entrant" + ppr LFThunk{} = text "thunk" + ppr LFCon{} = text "data-con" + ppr LFUnknown{} = text "unknown" + ppr LFUnlifted = text "unlifted" + ppr LFLetNoEscape = text "let-no-escape" ------------------------- -- StandardFormInfo tells whether this thunk has one of @@ -626,7 +633,7 @@ getCallMethod _ _name _ LFLetNoEscape _n_args _v_args (LneLoc blk_id lne_regs) _self_loop_info = JumpToIt blk_id lne_regs -getCallMethod _ name _ _lf_info _ _ _ _ = pprPanic "Unknown call method" (ppr name) +getCallMethod _ name _ _lf_info _ _ _loc _ = pprPanic "Unknown call method" (ppr name $$ ppr _lf_info $$ ppr _loc) ----------------------------------------------------------------------------- -- Data types for closure information ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -60,7 +60,7 @@ mkCgIdInfo id lf expr litIdInfo :: DynFlags -> Id -> LambdaFormInfo -> CmmLit -> CgIdInfo litIdInfo dflags id lf lit - = CgIdInfo { cg_id = id, cg_lf = lf + = pprTrace "litIdInfo" (ppr id) $ CgIdInfo { cg_id = id, cg_lf = lf , cg_loc = CmmLoc (addDynTag platform (CmmLit lit) tag) } where tag = lfDynTag dflags lf @@ -77,7 +77,8 @@ lneIdInfo platform id regs rhsIdInfo :: Id -> LambdaFormInfo -> FCode (CgIdInfo, LocalReg) rhsIdInfo id lf_info - = do platform <- getPlatform + = pprTrace "rhsIdInfo" (ppr id) $ + do platform <- getPlatform reg <- newTemp (gcWord platform) return (mkCgIdInfo id lf_info (CmmReg (CmmLocal reg)), reg) @@ -177,25 +178,26 @@ getNonVoidArgAmodes (arg:args) -- Interface functions for binding and re-binding names ------------------------------------------------------------------------ -bindToReg :: NonVoid Id -> LambdaFormInfo -> FCode LocalReg +bindToReg :: HasCallStack => NonVoid Id -> LambdaFormInfo -> FCode LocalReg -- Bind an Id to a fresh LocalReg bindToReg nvid@(NonVoid id) lf_info = do platform <- getPlatform let reg = idToReg platform nvid - addBindC (mkCgIdInfo id lf_info (CmmReg (CmmLocal reg))) + pprTrace "bindToReg" (ppr id $$ ppr lf_info $$ callStackDoc) + $ addBindC (mkCgIdInfo id lf_info (CmmReg (CmmLocal reg))) return reg -rebindToReg :: NonVoid Id -> FCode LocalReg +rebindToReg :: HasCallStack => NonVoid Id -> FCode LocalReg -- Like bindToReg, but the Id is already in scope, so -- get its LF info from the envt rebindToReg nvid@(NonVoid id) = do { info <- getCgIdInfo id ; bindToReg nvid (cg_lf info) } -bindArgToReg :: NonVoid Id -> FCode LocalReg +bindArgToReg :: HasCallStack => NonVoid Id -> FCode LocalReg bindArgToReg nvid@(NonVoid id) = bindToReg nvid (mkLFArgument id) -bindArgsToRegs :: [NonVoid Id] -> FCode [LocalReg] +bindArgsToRegs :: HasCallStack => [NonVoid Id] -> FCode [LocalReg] bindArgsToRegs args = mapM bindArgToReg args idToReg :: Platform -> NonVoid Id -> LocalReg ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -364,6 +364,7 @@ assignment. -} cgCase (StgApp v []) bndr alt_type@(PrimAlt _) alts | isUnliftedType (idType v) -- Note [Dodgy unsafeCoerce 1] + , not $ isJoinId v -- TODO: necessary as idInfoToAmode panics on LneLoc = -- assignment suffices for unlifted types do { platform <- getPlatform ; unless (reps_compatible platform) $ ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -1392,20 +1392,14 @@ keepAliveId -- keepAlive# -- :: forall (rep_a :: RuntimeRep) (a :: TYPE rep_a) -- (rep_r :: RuntimeRep) (r :: TYPE rep_r). - -- a - -- -> (State# RealWorld -> (# State# RealWorld, r #)) - -- -> State# RealWorld - -- -> (# State# RealWorld, r #) + -- a -> r -> r -- rep_a = runtimeRep1TyVar a = openAlphaTyVar rep_r = runtimeRep2TyVar r = openBetaTyVar ty = mkInvForAllTys [rep_a, a, rep_r, r] - $ mkVisFunTys [mkTyVarTy a, cont_ty, realWorldStatePrimTy] result_ty - cont_ty = realWorldStatePrimTy `mkVisFunTy` result_ty - -- (# State# RealWorld, r #) - result_ty = mkTupleTy Unboxed [realWorldStatePrimTy, mkTyVarTy r] + $ mkVisFunTys [mkTyVarTy a, mkTyVarTy r] (mkTyVarTy r) id_info = noCafIdInfo `setStrictnessInfo` mkClosedStrictSig [topDmd, strictApply1Dmd, topDmd] topDiv `setArityInfo` 3 ===================================== compiler/prelude/primops.txt.pp ===================================== @@ -3240,7 +3240,7 @@ primop SeqOp "seq#" GenPrimOp -- See Note [seq# magic] in GHC.Core.Op.ConstantFold pseudoop "keepAlive#" - o -> (State# RealWorld -> (# State# RealWorld, p #)) -> State# RealWorld -> (# State# RealWorld, p #) + o -> p -> p { TODO. } primop GetSparkOp "getSpark#" GenPrimOp ===================================== libraries/base/Foreign/Marshal/Alloc.hs ===================================== @@ -131,7 +131,7 @@ allocaBytes (I# size) action = IO $ \ s0 -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> let addr = Ptr (byteArrayContents# barr#) in case action addr of { IO action' -> - keepAlive# barr# action' s2 + keepAlive# barr# (action' s2) }}} allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b @@ -140,7 +140,7 @@ allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> let addr = Ptr (byteArrayContents# barr#) in case action addr of { IO action' -> - keepAlive# barr# action' s2 + keepAlive# barr# (action' s2) }}} -- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes' ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -412,7 +412,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r action# s + IO action# -> keepAlive# r (action# s) touchForeignPtr :: ForeignPtr a -> IO () ===================================== libraries/base/GHC/IO/Unsafe.hs ===================================== @@ -102,7 +102,7 @@ like 'Control.Exception.bracket' cannot be used safely within @since 4.4.0.0 -} unsafeDupablePerformIO :: IO a -> a -unsafeDupablePerformIO (IO m) = case runRW# m of (# _, a #) -> a +unsafeDupablePerformIO (IO m) = case runRW# (\s -> m s) of (# _, a #) -> a {-| 'unsafeInterleaveIO' allows an 'IO' computation to be deferred lazily. ===================================== libraries/base/GHC/ST.hs ===================================== @@ -135,5 +135,5 @@ instance Show (ST s a) where -- The @forall@ ensures that the internal state used by the 'ST' -- computation is inaccessible to the rest of the program. runST :: (forall s. ST s a) -> a -runST (ST st_rep) = case runRW# st_rep of (# _, a #) -> a +runST (ST st_rep) = case runRW# (\s -> st_rep s) of (# _, a #) -> a -- See Note [Definition of runRW#] in GHC.Magic ===================================== libraries/ghc-compact/GHC/Compact/Serialized.hs ===================================== @@ -90,7 +90,7 @@ withSerializedCompact (Compact buffer root lock) func = withMVar lock $ \_ -> do (# s', rootAddr #) -> (# s', Ptr rootAddr #) ) blockList <- mkBlockList buffer let serialized = SerializedCompact blockList rootPtr - IO (\s1 -> case func serialized of IO action' -> keepAlive# buffer action' s1) + IO (\s1 -> case func serialized of IO action' -> keepAlive# buffer (action' s1)) fixupPointers :: Addr# -> Addr# -> State# RealWorld -> (# State# RealWorld, Maybe (Compact a) #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0040f7ccaeb8a0f6945662c805eaa6c4bcc2023c...ae6dae6a6c4d668c2639764bee1e0bbf42c646d1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0040f7ccaeb8a0f6945662c805eaa6c4bcc2023c...ae6dae6a6c4d668c2639764bee1e0bbf42c646d1 You're receiving 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 18 21:15:56 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Sat, 18 Apr 2020 17:15:56 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/D5082 Message-ID: <5e9b6e0c3b63e_616765c7a285640248@gitlab.haskell.org.mail> John Ericson deleted branch wip/D5082 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 Sat Apr 18 22:00:17 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Sat, 18 Apr 2020 18:00:17 -0400 Subject: [Git][ghc/ghc][wip/T17173] 12 commits: Hadrian: fix dyn_o/dyn_hi rule (#17534) Message-ID: <5e9b78711fa24_616776d1c7456478b4@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 34287d9a by Simon Peyton Jones at 2020-04-18T22:53:29+01:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Core/Lint.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.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/e1fb31571f4eb16ea6fe2803a088d15bcbc5f0c4...34287d9a676b83a50e15acecbe0be2e7232f1987 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e1fb31571f4eb16ea6fe2803a088d15bcbc5f0c4...34287d9a676b83a50e15acecbe0be2e7232f1987 You're receiving 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 18 23:55:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 18 Apr 2020 19:55:54 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Add a missing zonk in tcHsPartialType Message-ID: <5e9b938ab5360_616776d1c745659895@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - b895317b by Alexis King at 2020-04-18T19:55:47-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45186e464a3f5a6d302debc930ef3376959ab707...b895317bff965a7f2aabc3bf83e118dff72b5fc0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45186e464a3f5a6d302debc930ef3376959ab707...b895317bff965a7f2aabc3bf83e118dff72b5fc0 You're receiving 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 19 07:16:17 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 19 Apr 2020 03:16:17 -0400 Subject: [Git][ghc/ghc][master] 2 commits: GHC.Core.Opt renaming Message-ID: <5e9bfac14b25a_6167134ebbc45681114@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - 30 changed files: - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15ab6cd548f284732a7f89d78c2b89b1bfc4ea1d...15312bbb53f247c9ed2c5cf75100a9f44c1c7227 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15ab6cd548f284732a7f89d78c2b89b1bfc4ea1d...15312bbb53f247c9ed2c5cf75100a9f44c1c7227 You're receiving 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 19 07:16:55 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 19 Apr 2020 03:16:55 -0400 Subject: [Git][ghc/ghc][master] Add missing addInScope call for letrec binders in OccurAnal Message-ID: <5e9bfae7eb497_6167134ebbc4568577d@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 1 changed file: - compiler/GHC/Core/Opt/OccurAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -843,7 +843,7 @@ occAnalNonRecBind env lvl imp_rule_edges bndr rhs body_usage occAnalRecBind :: OccEnv -> TopLevelFlag -> ImpRuleEdges -> [(Var,CoreExpr)] -> UsageDetails -> (UsageDetails, [CoreBind]) occAnalRecBind env lvl imp_rule_edges pairs body_usage - = foldr (occAnalRec env lvl) (body_usage, []) sccs + = foldr (occAnalRec rhs_env lvl) (body_usage, []) sccs -- For a recursive group, we -- * occ-analyse all the RHSs -- * compute strongly-connected components @@ -856,9 +856,11 @@ occAnalRecBind env lvl imp_rule_edges pairs body_usage nodes :: [LetrecNode] nodes = {-# SCC "occAnalBind.assoc" #-} - map (makeNode env imp_rule_edges bndr_set) pairs + map (makeNode rhs_env imp_rule_edges bndr_set) pairs - bndr_set = mkVarSet (map fst pairs) + bndrs = map fst pairs + bndr_set = mkVarSet bndrs + rhs_env = env `addInScope` bndrs {- Note [Unfoldings and join points] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eaed0a3289e4c24ff1a70c6fc4b7f8bae6cd2dd3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eaed0a3289e4c24ff1a70c6fc4b7f8bae6cd2dd3 You're receiving 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 19 10:27:54 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Sun, 19 Apr 2020 06:27:54 -0400 Subject: [Git][ghc/ghc][wip/andreask/inline_div] Always inline divInt and modInt in phase zero. Message-ID: <5e9c27aaa8177_616776d1c74570299@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inline_div at Glasgow Haskell Compiler / GHC Commits: 0ed37369 by Andreas Klebinger at 2020-04-19T12:27:44+02:00 Always inline divInt and modInt in phase zero. This prevents the overhead of a function call for operations which really only need to be a few instructions. By always inlining them in phase zero we can: * Match on them via rules in earlier phases. * Can constant fold on them in phase zero by rules on their underlying primitives. This fixes #18067 - - - - - 2 changed files: - libraries/base/GHC/Base.hs - libraries/ghc-prim/GHC/Classes.hs Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1545,9 +1545,36 @@ getTag x = dataToTag# x -- Definitions of the boxed PrimOps; these will be -- used in the case of partial applications, etc. +{- Note [Inlining divInt, modInt] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + divInt and modInt are implemented by calling unboxed + variants, which themselves are implemented in terms of + the quotInt#/remInt# primOps. + + My marking the boxed versions as INLINE[1] we achieve two things: + + * The strength reduction rules which are operating on divInt#/remInt# + can already fire in phase 1. + * We can inline any constant argument in Phase zero optimizing the + general case somewhat. + + This solves #18067 where we observed divInt ending up + as a uninlined call to divInt# at times. + + TODO: It might be good to apply the same pattern to + quotRemInt and divModInt. But I have not looked at this + yet. + +-} + {-# INLINE quotInt #-} {-# INLINE remInt #-} +-- See Note [Inlining divInt, modInt] +{-# INLINE[1] divInt #-} +{-# INLINE[1] modInt #-} + quotInt, remInt, divInt, modInt :: Int -> Int -> Int (I# x) `quotInt` (I# y) = I# (x `quotInt#` y) (I# x) `remInt` (I# y) = I# (x `remInt#` y) ===================================== libraries/ghc-prim/GHC/Classes.hs ===================================== @@ -545,8 +545,8 @@ not False = True -- put them -- These functions have built-in rules. -{-# NOINLINE [0] divInt# #-} -{-# NOINLINE [0] modInt# #-} +{-# INLINE [0] divInt# #-} +{-# INLINE [0] modInt# #-} divInt# :: Int# -> Int# -> Int# x# `divInt#` y# -- Be careful NOT to overflow if we do any additional arithmetic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ed373698572aed88cf91553368a1dfa9767b749 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ed373698572aed88cf91553368a1dfa9767b749 You're receiving 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 19 13:42:19 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Sun, 19 Apr 2020 09:42:19 -0400 Subject: [Git][ghc/ghc][wip/lexical-negation] 39 commits: testsuite: Fix comment for a language extension Message-ID: <5e9c553bcfaf1_6167124c91105726418@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/lexical-negation at Glasgow Haskell Compiler / GHC Commits: 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 035b5d1f by Vladislav Zavialov at 2020-04-19T16:42:10+03:00 Implement -XLexicalNegation (GHC Proposal #229) This patch introduces a new extension, -XLexicalNegation, which detects whether the minus sign stands for negation or subtraction using the whitespace-based rules described in GHC Proposal #229. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d433ff8bf82c10da408a70f8945f6c790065a69c...035b5d1ff464bd8c4bdaab30855d1bc1f2f1f748 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d433ff8bf82c10da408a70f8945f6c790065a69c...035b5d1ff464bd8c4bdaab30855d1bc1f2f1f748 You're receiving 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 19 15:01:58 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Sun, 19 Apr 2020 11:01:58 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] 706 commits: ci: push perf test metrics even when the testsuite doesn't pass Message-ID: <5e9c67e690ce6_6167136dfb9c5734190@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: f8ec32d7 by Alp Mestanogullari at 2019-11-11T11:36:44-05:00 ci: push perf test metrics even when the testsuite doesn't pass The corresponding commit might introduce a regression on a perf test, in which case we certainly want to record it. The testsuite might also fail because of a test unrelated to performance, in which case we want to record that the perf test results were good. Either way, we likely want to record them under all circumstances but we don't without this patch. Metric Decrease: T3586 Metric Increase: lazy-bs-alloc - - - - - 643d42fc by Alp Mestanogullari at 2019-11-12T18:40:19-05:00 testsuite: don't collect compiler stats in collect_runtime_residency We instead want to collect the runtime stats (with collect_stats, instead of collect_compiler_stats). This should fix a number of perf tests failures we have been seeing, where we suddenly started measuring metrics we didn't intend to measure, which tend to fall outside of the acceptance window. Metric Decrease: lazy-bs-alloc T3586 Metric Increase: space_leak_001 T4801 T5835 T12791 - - - - - 535d0edc by Ömer Sinan Ağacan at 2019-11-13T07:06:12-05:00 Document CmmTopInfo type [ci skip] - - - - - 2d4f9ad8 by Ben Gamari at 2019-11-13T07:06:49-05:00 Ensure that coreView/tcView are able to inline Previously an import cycle between Type and TyCoRep meant that several functions in TyCoRep ended up SOURCE import coreView. This is quite unfortunate as coreView is intended to be fused into a larger pattern match and not incur an extra call. Fix this with a bit of restructuring: * Move the functions in `TyCoRep` which depend upon things in `Type` into `Type` * Fold contents of `Kind` into `Type` and turn `Kind` into a simple wrapper re-exporting kind-ish things from `Type` * Clean up the redundant imports that popped up as a result Closes #17441. Metric Decrease: T4334 - - - - - b795637f by Alp Mestanogullari at 2019-11-13T07:07:28-05:00 hadrian: fix Windows CI script By only using 'export' from within bash commands. - - - - - 6885e22c by Ben Gamari at 2019-11-13T07:08:03-05:00 testsuite: Add test for #17458 As noted in #17458, QuantifiedConstraints and UndecideableInstances could previously be used to write programs which can loop at runtime. This was fixed in !1870. - - - - - b4b19d89 by Ben Gamari at 2019-11-13T07:08:03-05:00 users guide: Fix broken link - - - - - 9a939a6c by Ryan Scott at 2019-11-13T07:08:40-05:00 Print name prefixly in the Outputable instance for StandaloneKindSig Issue #17461 was occurring because the `Outputable` instance for standalone kind signatures was simply calling `ppr` on the name in the kind signature, which does not add parentheses to infix names. The solution is simple: use `pprPrefixOcc` instead. Fixes #17461. - - - - - a06cfb59 by Ömer Sinan Ağacan at 2019-11-13T07:09:18-05:00 Only pass mod_location with HscRecomp instead of the entire ModSummary HscRecomp users only need the ModLocation of the module being compiled, so only pass that to users instead of the entire ModSummary Metric Decrease: T4801 - - - - - dd49b3f0 by Ben Gamari at 2019-11-13T17:01:21-05:00 Bump Haskeline and add exceptions as boot library Haskeline now depends upon exceptions. See #16752. - - - - - b06b1858 by Ben Gamari at 2019-11-14T11:30:20-05:00 base: Bump version to 4.14.0.0 Metric Increase: T4801 - - - - - 6ab80439 by Ben Gamari at 2019-11-14T23:05:30-05:00 gitlab-ci: Allow Windows to fail again - - - - - 46afc380 by Ben Gamari at 2019-11-15T09:45:36-05:00 gitlab-ci: Install process to global pkgdb before starting build This is an attempt to mitigate #17480 by ensuring that a functional version of the process library is available before attempting the build. - - - - - 8c5cb806 by Ben Gamari at 2019-11-15T10:45:55-05:00 Bump supported LLVM version to 9.0 - - - - - 8e5851f0 by Ben Gamari at 2019-11-15T10:45:55-05:00 llvm-targets: Update with Clang 9 - - - - - f3ffec27 by Ben Gamari at 2019-11-15T11:54:26-05:00 testsuite: Increase acceptance window of T4801 This statistic is rather unstable. Hopefully fixes #17475. - - - - - c2991f16 by Ben Gamari at 2019-11-15T11:56:10-05:00 users-guide: Drop 8.6.1 release notes - - - - - e8da1354 by Ben Gamari at 2019-11-17T06:48:16-05:00 gitlab-ci: Fix submodule linter We ran it against the .git directory despite the fact that the linter wants to be run against the repository. - - - - - 13290f91 by Ben Gamari at 2019-11-17T06:48:16-05:00 Bump version to 8.10.0 Bumps haddock submodule. - - - - - fa98f823 by Ben Gamari at 2019-11-17T06:48:16-05:00 testsuite: Don't collect residency for T4801 I previously increased the size of the acceptance window from 2% to 5% but this still isn't enough. Regardless, measuring bytes allocated should be sufficient to catch any regressions. - - - - - 002b2842 by Ivan Kasatenko at 2019-11-17T06:49:22-05:00 Make test 16916 more stable across runs - - - - - ca89dd3b by Ben Gamari at 2019-11-17T06:58:17-05:00 users-guide: Address #17329 Adopts the language suggested by @JakobBruenker. - - - - - 2f5ed225 by Ben Gamari at 2019-11-17T07:16:32-05:00 exceptions: Bump submodule back to master The previous commit hasn't made it to master yet. - - - - - 34515e7c by nineonine at 2019-11-17T13:33:22-08:00 Fix random typos [skip ci] - - - - - 4a37a29b by Mario Blažević at 2019-11-17T17:26:24-05:00 Fixed issue #17435, missing Data instances - - - - - 97f1bcae by Andreas Klebinger at 2019-11-17T17:26:24-05:00 Turn some comments into GHC.Hs.Utils into haddocks - - - - - cf7f8e5b by Ben Gamari at 2019-11-17T17:26:26-05:00 testsuite: Skip T17414 on Linux It is typical for $TMP to be a small tmpfson Linux. This test will fail in such cases since we must create a file larger than the filesystem. See #17459. - - - - - 88013b78 by nineonine at 2019-11-19T11:53:16-05:00 Optimize MonadUnique instances based on IO (#16843) Metric Decrease: T14683 - - - - - a8adb5b4 by Ben Gamari at 2019-11-19T11:53:55-05:00 desugar: Drop stale Note [Matching seqId] The need for this note vanished in eae703aa60f41fd232be5478e196b661839ec3de. - - - - - 08d595c0 by Ben Gamari at 2019-11-19T11:53:55-05:00 Give seq a more precise type and remove magic `GHC.Prim.seq` previously had the rather plain type: seq :: forall a b. a -> b -> b However, it also had a special typing rule to applications where `b` is not of kind `Type`. Issue #17440 noted that levity polymorphism allows us to rather give it the more precise type: seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b This allows us to remove the special typing rule that we previously required to allow applications on unlifted arguments. T9404 contains a non-Type application of `seq` which should verify that this works as expected. Closes #17440. - - - - - ec8a463d by Viktor Dukhovni at 2019-11-19T11:54:45-05:00 Enable USE_PTHREAD_FOR_ITIMER also on FreeBSD If using a pthread instead of a timer signal is more reliable, and has no known drawbacks, then FreeBSD is also capable of supporting this mode of operation (tested on FreeBSD 12 with GHC 8.8.1, but no reason why it would not also work on FreeBSD 11 or GHC 8.6). Proposed by Kevin Zhang in: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=241849 - - - - - cd40e12a by Ömer Sinan Ağacan at 2019-11-19T11:55:36-05:00 Packages.hs: use O(n*log(n)) ordNub instead of O(n*n) nub As reported in #8173 in some environments package lists can get quite long, so we use more efficient ordNub instead of nub on package lists. - - - - - 2b27cc16 by Ben Gamari at 2019-11-19T11:56:21-05:00 Properly account for libdw paths in make build system Should finally fix #17255. - - - - - 0418c38d by Ben Gamari at 2019-11-19T11:56:58-05:00 rts: Add missing include of SymbolExtras.h This broke the Windows build. - - - - - c819c0e4 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Use correct info table pointer accessor Previously we used INFO_PTR_TO_STRUCT instead of THUNK_INFO_PTR_TO_STRUCT when looking at a thunk. These two happen to be equivalent on 64-bit architectures due to alignment considerations however they are different on 32-bit platforms. This lead to #17487. To fix this we also employ a small optimization: there is only one thunk of type WHITEHOLE (namely stg_WHITEHOLE_info). Consequently, we can just use a plain pointer comparison instead of testing against info->type. - - - - - deed8e31 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Fix incorrect masking in mark queue type test We were using TAG_BITS instead of TAG_MASK. This happened to work on 64-bit platforms where TAG_BITS==3 since we only use tag values 0 and 3. However, this broken on 32-bit platforms where TAG_BITS==2. - - - - - 097f8072 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Rework mark queue representation The previous representation needlessly limited the array length to 16-bits on 32-bit platforms. - - - - - eb7b233a by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Fix handling on large object marking on 32-bit Previously we would reset the pointer pointing to the object to be marked to the beginning of the block when marking a large object. This did no harm on 64-bit but on 32-bit it broke, e.g. `arr020`, since we align pinned ByteArray allocations such that the payload is 8 byte-aligned. This means that the object might not begin at the beginning of the block., - - - - - a7571a74 by Ben Gamari at 2019-11-19T11:57:36-05:00 testsuite: Increase width of stack003 test Previously the returned tuple seemed to fit in registers on amd64. This meant that non-moving collector bug would cause the test to fail on i386 yet not amd64. - - - - - 098d5017 by Ben Gamari at 2019-11-19T11:57:36-05:00 nonmoving: Drop redundant write barrier on stack underflow Previously we would push stack-carried return values to the new stack on a stack overflow. While the precise reasoning for this barrier is unfortunately lost to history, in hindsight I suspect it was prompted by a missing barrier elsewhere (that has been since fixed). Moreover, there the redundant barrier is actively harmful: the stack may contain non-pointer values; blindly pushing these to the mark queue will result in a crash. This is precisely what happened in the `stack003` test. However, because of a (now fixed) deficiency in the test this crash did not trigger on amd64. - - - - - e57b7cc6 by Roland Zumkeller at 2019-11-19T20:39:19-05:00 Changing Thread IDs from 32 bits to 64 bits. - - - - - d1f3c637 by Roland Zumkeller at 2019-11-19T20:39:19-05:00 Use pointer equality in Eq/Ord for ThreadId Changes (==) to use only pointer equality. This is safe because two threads are the same iff they have the same id. Changes `compare` to check pointer equality first and fall back on ids only in case of inequality. See discussion in #16761. - - - - - ef8a08e0 by Alexey Kuleshevich at 2019-11-19T20:39:20-05:00 hpc: Fix encoding issues. Add test for and fix #17073 * Make sure files are being read/written in UTF-8. Set encoding while writing HTML output. Also set encoding while writing and reading .tix files although we don't yet have a ticket complaining that this poses problems. * Set encoding in html header to utf8 * Upgrade to new version of 'hpc' library and reuse `readFileUtf8` and `writeFileUtf8` functions * Update git submodule for `hpc` * Bump up `hpc` executable version Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - b79e46d6 by Vladislav Zavialov at 2019-11-19T20:39:20-05:00 Strip parentheses in expressions contexts in error messages This makes error messages a tad less noisy. - - - - - 13bbde77 by Ben Gamari at 2019-11-21T13:56:56-05:00 Bump hsc2hs submodule Including Phyx's backport of the process changes fixing #17480. - - - - - d4d10501 by Ben Gamari at 2019-11-23T09:42:38-05:00 Bump hsc2hs submodule again This fixes the Darwin build. - - - - - 889d475b by nineonine at 2019-11-23T18:53:29-05:00 Fix typo in Note reference [skip ci] - - - - - 8a33abfc by Ryan Scott at 2019-11-23T18:54:05-05:00 Target the IsList instance for ZipList at base-4.14.0.0 (#17489) This moves the changelog entry about the instance from `base-4.15.0.0` to `base-4.14.0.0`. This accomplishes part (1) from #17489. [ci skip] - - - - - e43e6ece by Ben Gamari at 2019-11-23T18:54:41-05:00 rts: Expose interface for configuring EventLogWriters This exposes a set of interfaces from the GHC API for configuring EventLogWriters. These can be used by consumers like [ghc-eventlog-socket](https://github.com/bgamari/ghc-eventlog-socket). - - - - - de6bbdf2 by Matheus Magalhães de Alcantara at 2019-11-23T18:55:23-05:00 Take care to not eta-reduce jumps in CorePrep CorePrep already had a check to prevent it from eta-reducing Ids that respond true to hasNoBinding (foreign calls, constructors for unboxed sums and products, and Ids with compulsory unfoldings). It did not, however, consider join points as ids that 'must be saturated'. Checking whether the Id responds True to 'isJoinId' should prevent CorePrep from turning saturated jumps like the following (from #17429) into undersaturated ones: (\ eta_XP -> join { mapped_s1vo _ = lvl_s1vs } in jump mapped_s1vo eta_XP) - - - - - 4a1e7e47 by Matheus Magalhães de Alcantara at 2019-11-23T18:55:23-05:00 Make CorePrep.tryEtaReducePrep and CoreUtils.tryEtaReduce line up Simon PJ says he prefers this fix to #17429 over banning eta-reduction for jumps entirely. Sure enough, this also works. Test case: simplCore/should_compile/T17429.hs - - - - - 15f1dc33 by Ryan Scott at 2019-11-23T18:56:00-05:00 Prevent -optc arguments from being duplicated in reverse order (#17471) This reverts a part of commit 7bc5d6c6578ab9d60a83b81c7cc14819afef32ba that causes all arguments to `-optc` (and `-optcxx`) to be passed twice to the C/C++ compiler, once in reverse order and then again in the correct order. While passing duplicate arguments is usually harmless it can cause breakage in this pattern, which is employed by Hackage libraries in the wild: ``` ghc Foo.hs foo.c -optc-D -optcFOO ``` As `FOO -D -D FOO` will cause compilers to error. Fixes #17471. - - - - - e85c9b22 by Ben Gamari at 2019-11-23T18:56:36-05:00 Bump ghc version to 8.11 - - - - - 0e6c2045 by Ben Gamari at 2019-11-23T18:57:12-05:00 rts: Consolidate spinlock implementation Previously we had two distinct implementations: one with spinlock profiling and another without. This seems like needless duplication. - - - - - cb11fcb5 by Ben Gamari at 2019-11-23T18:57:49-05:00 Packages: Don't use expectJust Throw a slightly more informative error on failure. Motivated by the errors seen in !2160. - - - - - 5747ebe9 by Sebastian Graf at 2019-11-23T18:58:25-05:00 Stricten functions ins GHC.Natural This brings `Natural` on par with `Integer` and fixes #17499. Also does some manual CSE for 0 and 1 literals. - - - - - c14b723f by Ömer Sinan Ağacan at 2019-11-23T18:59:06-05:00 Bump exceptions submodule Adds a few files generated by GHC's configure script to .gitignore - - - - - 7b4c7b75 by Brian Wignall at 2019-11-23T19:04:52-05:00 Fix typos - - - - - 6008206a by Viktor Dukhovni at 2019-11-24T14:33:18-05:00 On FreeBSD 12 sys/sysctl.h requires sys/types.h Else build fails with: In file included from ExecutablePath.hsc:42: /usr/include/sys/sysctl.h:1062:25: error: unknown type name 'u_int'; did you mean 'int'? int sysctl(const int *, u_int, void *, size_t *, const void *, size_t); ^~~~~ int compiling libraries/base/dist-install/build/System/Environment/ExecutablePath_hsc_make.c failed (exit code 1) Perhaps also also other FreeBSD releases, but additional include will no harm even if not needed. - - - - - b694b566 by Ben Gamari at 2019-11-24T14:33:54-05:00 configure: Fix HAVE_C11_ATOMICS macro Previously we were using AC_DEFINE instead of AC_DEFINE_UNQUOTED, resulted in the variable not being interpolated. Fixes #17505. - - - - - 8b8dc366 by Krzysztof Gogolewski at 2019-11-25T14:37:38+01:00 Remove prefix arrow support for GADTs (#17211) This reverts the change in #9096. The specialcasing done for prefix (->) is brittle and does not support VTA, type families, type synonyms etc. - - - - - 5a08f7d4 by Sebastian Graf at 2019-11-27T00:14:59-05:00 Make warnings for TH splices opt-in In #17270 we have the pattern-match checker emit incorrect warnings. The reason for that behavior is ultimately an inconsistency in whether we treat TH splices as written by the user (`FromSource :: Origin`) or as generated code (`Generated`). This was first reported in #14838. The current solution is to TH splices as `Generated` by default and only treat them as `FromSource` when the user requests so (-fenable-th-splice-warnings). There are multiple reasons for opt-in rather than opt-out: * It's not clear that the user that compiles a splice is the author of the code that produces the warning. Think of the situation where she just splices in code from a third-party library that produces incomplete pattern matches. In this scenario, the user isn't even able to fix that warning. * Gathering information for producing the warnings (pattern-match check warnings in particular) is costly. There's no point in doing so if the user is not interested in those warnings. Fixes #17270, but not #14838, because the proper solution needs a GHC proposal extending the TH AST syntax. - - - - - 8168b42a by Vladislav Zavialov at 2019-11-27T11:32:18+03:00 Whitespace-sensitive bang patterns (#1087, #17162) This patch implements a part of GHC Proposal #229 that covers five operators: * the bang operator (!) * the tilde operator (~) * the at operator (@) * the dollar operator ($) * the double dollar operator ($$) Based on surrounding whitespace, these operators are disambiguated into bang patterns, lazy patterns, strictness annotations, type applications, splices, and typed splices. This patch doesn't cover the (-) operator or the -Woperator-whitespace warning, which are left as future work. - - - - - 9e5477c4 by Ryan Scott at 2019-11-27T20:01:50-05:00 Fix @since annotations for isResourceVanishedError and friends (#17488) - - - - - e122ba33 by Sergei Trofimovich at 2019-11-27T20:02:29-05:00 .gitmodules: tweak 'exception' URL to avoid redirection warnings Avoid initial close warning of form: ``` Cloning into 'exceptions'... warning: redirecting to https://gitlab.haskell.org/ghc/packages/exceptions.git/ ``` Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f84b52a by Philipp Krüger at 2019-11-28T02:54:05-05:00 Reduce boolean blindness in OccInfo(OneOcc) #17482 * Transformed the type aliases `InterestingCxt`, `InsideLam` and `OneBranch` into data types. * Added Semigroup and Monoid instances for use in orOccInfo in OccurAnal.hs * Simplified some usage sites by using pattern matching instead of boolean algebra. Metric Increase: T12150 This increase was on a Mac-build of exactly 1%. This commit does *not* re-intruduce the asymptotic memory usage described in T12150. - - - - - 3748ba3a by Brian Wignall at 2019-11-28T02:54:52-05:00 Fix typos, using Wikipedia list of common typos - - - - - 6c59cc71 by Stefan Schulze Frielinghaus at 2019-11-28T02:55:33-05:00 Fix endian handling of LLVM backend Get rid of CPP macro WORDS_BIGENDIAN which is not defined anymore, and replace it by DynFlag. This fixes partially #17337. - - - - - 6985e0fc by Vladislav Zavialov at 2019-11-28T15:47:53+03:00 Factor out HsSCC/HsCoreAnn/HsTickPragma into HsPragE This is a refactoring with no user-visible changes (except for GHC API users). Consider the HsExpr constructors that correspond to user-written pragmas: HsSCC representing {-# SCC ... #-} HsCoreAnn representing {-# CORE ... #-} HsTickPragma representing {-# GENERATED ... #-} We can factor them out into a separate datatype, HsPragE. It makes the code a bit tidier, especially in the parser. Before this patch: hpc_annot :: { Located ( (([AddAnn],SourceText),(StringLiteral,(Int,Int),(Int,Int))), ((SourceText,SourceText),(SourceText,SourceText)) ) } After this patch: prag_hpc :: { Located ([AddAnn], HsPragE GhcPs) } - - - - - 7f695a20 by Ömer Sinan Ağacan at 2019-11-29T08:25:28-05:00 Pass ModDetails with (partial) ModIface in HscStatus (Partial) ModIface and ModDetails are generated at the same time, but they're passed differently: ModIface is passed in HscStatus consturctors while ModDetails is returned in a tuple. This refactors ModDetails passing so that it's passed around with ModIface in HscStatus constructors. This makes the code more consistent and hopefully easier to understand: ModIface and ModDetails are really very closely related. It makes sense to treat them the same way. - - - - - e921c90f by Ömer Sinan Ağacan at 2019-11-29T08:26:07-05:00 Improve few Foreign.Marshal.Utils docs In copyBytes and moveBytes mention which argument is source and which is destination. Also fixes some of the crazy indentation in the module and cleans trailing whitespace. - - - - - 316f2431 by Sebastian Graf at 2019-11-30T02:57:58-05:00 Hadrian docs: Rename the second "validate" entry to "slow-validate" [ci skip] That would be in line with the implementation. - - - - - 5aba5d32 by Vladislav Zavialov at 2019-11-30T02:58:34-05:00 Remove HasSrcSpan (#17494) Metric Decrease: haddock.compiler - - - - - d1de5c22 by Sylvain Henry at 2019-11-30T02:59:13-05:00 Use Hadrian by default in validate script (#17527) - - - - - 3a96a0b6 by Sebastian Graf at 2019-11-30T02:59:55-05:00 Simpler Semigroup instance for InsideLam and InterestingCtxt This mirrors the definition of `(&&)` and `(||)` now, relieving the Simplifier of a marginal amount of pressure. - - - - - f8cfe81a by Roland Senn at 2019-11-30T20:33:49+01:00 Improve tests for #17171 While backporting MR !1806 to 8.8.2 (!1885) I learnt the following: * Tests with `expect_fail` do not compare `*.stderr` output files. So a test using `expect_fail` will not detect future regressions on the `stderr` output. * To compare the `*.stderr` output files, I have to use the `exit_code(n)` function. * When a release is made, tests with `makefile_test` are converted to use `run_command`. * For the test `T17171a` the return code is `1` when running `makefile_test`, however it's `2` when running `run_command`. Therefore I decided: * To improve my tests for #17171 * To change test T17171a from `expect_fail` to `exit_code(2)` * To change both tests from `makefile_test` to `run_command` - - - - - 2b113fc9 by Vladislav Zavialov at 2019-12-01T08:17:05-05:00 Update DisambECP-related comments - - - - - beed7c3e by Ben Gamari at 2019-12-02T03:41:37-05:00 testsuite: Fix location of typing_stubs module This should fix the build on Debian 8. - - - - - 53251413 by Ben Gamari at 2019-12-02T03:42:14-05:00 testsuite: Don't override LD_LIBRARY_PATH, only prepend NixOS development environments often require that LD_LIBRARY_PATH be set in order to find system libraries. T1407 was overriding LD_LIBRARY_PATH, dropping these directories. Now it merely prepends, its directory. - - - - - 65400314 by Krzysztof Gogolewski at 2019-12-02T03:42:57-05:00 Convert warnings into assertions Since the invariants always hold in the testsuite, we can convert them to asserts. - - - - - 18baed64 by Alan Zimmerman at 2019-12-02T03:43:37-05:00 API Annotations: Unicode '->' on HsForallTy The code fragment type family Proxy2' ∷ ∀ k → k → Type where Proxy2' = Proxy' Generates AnnRarrow instead of AnnRarrowU for the first →. Fixes #17519 - - - - - 717f3236 by Brian Wignall at 2019-12-02T03:44:16-05:00 Fix more typos - - - - - bde48f8e by Ben Gamari at 2019-12-02T11:55:34-05:00 More Haddock syntax in GHC.Hs.Utils As suggested by RyanGlScott in !2163. - - - - - 038bedbc by Ben Gamari at 2019-12-02T11:56:18-05:00 Simplify: Fix pretty-printing of strictness A colleague recently hit the panic in Simplify.addEvals and I noticed that the message is quite unreadable due to incorrect pretty-printing. Fix this. - - - - - c500f652 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix changelog linting logic - - - - - 8ead967d by Ben Gamari at 2019-12-02T11:56:54-05:00 win32-init: Drop workaround for #17480 The `process` changes have now been merged into `hsc2hs`. (cherry picked from commit fa029f53132ad59f847ed012d3b835452cf16615) - - - - - d402209a by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Disable Sphinx build on Debian 8 The docutils version available appears to be too old to support the `table` directive's `:widths:` options. (cherry picked from commit 75764487a96a7a026948b5af5022781872d12baa) - - - - - f1f68824 by Ben Gamari at 2019-12-02T11:56:54-05:00 base: Fix <unistd.h> #include Previously we were including <sys/unistd.h> which is available on glibc but not musl. (cherry picked from commit e44b695ca7cb5f3f99eecfba05c9672c6a22205e) - - - - - 37eb94b3 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Bump Docker images Installs pxz on Centos7 (cherry picked from commit 86960e691f7a600be247c32a7cf795bf9abf7cc4) - - - - - aec98a79 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: pxz is unavailable on CentOS 7 Fall back to xz - - - - - 6708b8e5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Set LANG on CentOS 7 It otherwise seems to default to ascii - - - - - 470ef0e7 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Consolidate release build configuration - - - - - 38338757 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add Debian 10 builds - - - - - 012f13b5 by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Fix Windows bindist collection Apparently variable interpolation in the `artifacts.paths` key of `gitlab-ci.yml` doesn't work on Windows as it does on WIndows. (cherry picked from commit 100cc756faa4468ed6950116bae30609c1c3468b) - - - - - a0f09e23 by Ben Gamari at 2019-12-02T11:56:54-05:00 testsuite: Simplify Python <3.5 fallback for TextIO (cherry picked from commit d092d8598694c23bc07cdcc504dff52fa5f33be1) - - - - - 2b2370ec by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Add release-x86_64-linux-deb9 job (cherry picked from commit cbedb3c4a90649f474cb716842ba53afc5a642ca) - - - - - b1c206fd by Ben Gamari at 2019-12-02T11:56:54-05:00 gitlab-ci: Always build source tarball (cherry picked from commit 67b5de88ef923971f1980335137e3c7193213abd) - - - - - 4cbd5b47 by Sergei Trofimovich at 2019-12-02T11:57:33-05:00 configure.ac: make cross-compiler detection stricter Be more precise at detecting cross-compilation case. Before the change configuration $ ./configure --host=x86_64-pc-linux-gnu --target=x86_64-gentoo-linux-musl was not considered a cross-target. Even though libcs are different (`glibc` vs. `musl`). Without this patch build fails as: ``` "inplace/bin/ghc-cabal" check libraries/integer-gmp "inplace/bin/ghc-cabal" configure libraries/integer-gmp dist-install \ --with-ghc="/home/slyfox/dev/git/ghc/inplace/bin/ghc-stage1" \ --with-ghc-pkg="/home/slyfox/dev/git/ghc/inplace/bin/ghc-pkg" \ --disable-library-for-ghci --enable-library-vanilla --enable-library-for-ghci \ --enable-library-profiling --enable-shared --with-hscolour="/usr/bin/HsColour" \ --configure-option=CFLAGS="-Wall \ -Werror=unused-but-set-variable -Wno-error=inline \ -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp" \ --configure-option=LDFLAGS=" " --configure-option=CPPFLAGS=" \ " --gcc-options="-Wall -Werror=unused-but-set-variable -Wno-error=inline -iquote /home/slyfox/dev/git/ghc/libraries/integer-gmp \ " --with-gcc="x86_64-gentoo-linux-musl-gcc" --with-ld="x86_64-gentoo-linux-musl-ld.gold" --with-ar="x86_64-gentoo-linux-musl-ar" \ --with-alex="/usr/bin/alex" --with-happy="/usr/bin/happy" Configuring integer-gmp-1.0.2.0... configure: WARNING: unrecognized options: --with-compiler checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking target system type... x86_64-pc-linux-gnu checking for gcc... /usr/lib/ccache/bin/x86_64-gentoo-linux-musl-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... configure: error: in `/home/slyfox/dev/git/ghc/libraries/integer-gmp/dist-install/build': configure: error: cannot run C compiled programs. If you meant to cross compile, use `--host'. See `config.log' for more details make[1]: *** [libraries/integer-gmp/ghc.mk:5: libraries/integer-gmp/dist-install/package-data.mk] Error 1 make: *** [Makefile:126: all] Error 2 ``` Note: here `ghc-stage1` is assumed to target `musl` target but is passed `glibc` toolchain. It happens because initial ./configure phase did not detect host/target as different. Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org> - - - - - 5f7cb423 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Add `timesInt2#` primop - - - - - fbbe18a2 by Sylvain Henry at 2019-12-02T23:59:29-05:00 Use the new timesInt2# primop in integer-gmp (#9431) - - - - - 5a4b8d0c by Athas at 2019-12-03T00:00:09-05:00 Document RTS behaviour upon encountering '--'. - - - - - 705a16df by Ben Gamari at 2019-12-03T07:11:33-05:00 Make BCO# lifted In #17424 Simon PJ noted that there is a potentially unsafe occurrence of unsafeCoerce#, coercing from an unlifted to lifted type. However, nowhere in the compiler do we assume that a BCO# is not a thunk. Moreover, in the case of a CAF the result returned by `createBCO` *will* be a thunk (as noted in [Updatable CAF BCOs]). Consequently it seems better to rather make BCO# a lifted type and rename it to BCO. - - - - - 35afe4f3 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Use Int# primops in `Bits Int{8,16,32,64}` instances - - - - - 7a51b587 by Sylvain Henry at 2019-12-03T07:12:13-05:00 Add constant folding rule (#16402) narrowN (x .&. m) m .&. (2^N-1) = 2^N-1 ==> narrowN x e.g. narrow16 (x .&. 0x12FFFF) ==> narrow16 x - - - - - 10caee7f by Ben Gamari at 2019-12-03T21:04:50-05:00 users-guide: Add 8.12.1 release notes - - - - - 25019d18 by Ben Gamari at 2019-12-03T21:04:50-05:00 Drop Uniquable constraint for AnnTarget This relied on deriveUnique, which was far too subtle to be safely applied. Thankfully the instance doesn't appear to be used so let's just drop it. - - - - - 78b67ad0 by Ben Gamari at 2019-12-03T21:04:50-05:00 Simplify uniqAway This does two things: * Eliminate all uses of Unique.deriveUnique, which was quite easy to mis-use and extremely subtle. * Rename the previous "derived unique" notion to "local unique". This is possible because the only places where `uniqAway` can be safely used are those where local uniqueness (with respect to some InScopeSet) is sufficient. * Rework the implementation of VarEnv.uniqAway, as discussed in #17462. This should make the operation significantly more efficient than its previous iterative implementation.. Metric Decrease: T9872c T12227 T9233 T14683 T5030 T12545 hie002 Metric Increase: T9961 - - - - - f03a41d4 by Ben Gamari at 2019-12-03T21:05:27-05:00 Elf: Fix link info note generation Previously we would use the `.int` assembler directive to generate 32-bit words in the note section. However, `.int` is note guaranteed to produce 4-bytes; in fact, on some platforms (e.g. AArch64) it produces 8-bytes. Use the `.4bytes` directive to avoid this. Moreover, we used the `.align` directive, which is quite platform dependent. On AArch64 it appears to not even be idempotent (despite what the documentation claims). `.balign` is consequentially preferred as it offers consistent behavior across platforms. - - - - - 84585e5e by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Meaning-preserving SCC annotations (#15730) This patch implements GHC Proposal #176: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0176-scc-parsing.rst Before the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = 1.0 After the change: 1 / 2 / 2 = 0.25 1 / {-# SCC "name" #-} 2 / 2 = parse error - - - - - e49e5470 by Vladislav Zavialov at 2019-12-05T16:07:44-05:00 Improve error messages for SCC pragmas - - - - - a2b535d9 by Ben Gamari at 2019-12-05T16:07:45-05:00 users guide: Try to silence underfull \hbox warnings We use two tricks, as suggested here [1]: * Use microtype to try to reduce the incidence of underfull boxes * Bump up \hbadness to eliminate the warnings - - - - - 4e47217f by Bodigrim at 2019-12-05T16:07:47-05:00 Make sameNat and sameSymbol proxy-polymorphic - - - - - 8324f0b7 by Bodigrim at 2019-12-05T16:07:47-05:00 Test proxy-polymorphic sameNat and sameSymbol - - - - - 69001f54 by Ben Gamari at 2019-12-05T16:07:48-05:00 nonmoving: Clear segment bitmaps during sweep Previously we would clear the bitmaps of segments which we are going to sweep during the preparatory pause. However, this is unnecessary: the existence of the mark epoch ensures that the sweep will correctly identify non-reachable objects, even if we do not clear the bitmap. We now defer clearing the bitmap to sweep, which happens concurrently with mutation. - - - - - 58a9c429 by Ben Gamari at 2019-12-05T16:07:48-05:00 testsuite: Disable divByZero on non-NCG targets The LLVM backend does not guarantee any particular semantics for division by zero, making this test unreliable across platforms. - - - - - 8280bd8a by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Factor out terminal coloring - - - - - 92a52aaa by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Make performance metric summary more readable Along with some refactoring. - - - - - c4ca29c7 by Ben Gamari at 2019-12-05T16:07:49-05:00 testsuite: Use colors more consistently - - - - - 3354c68e by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Pretty-printing of the * kind Before this patch, GHC always printed the * kind unparenthesized. This led to two issues: 1. Sometimes GHC printed invalid or incorrect code. For example, GHC would print: type F @* x = x when it meant to print: type F @(*) x = x In the former case, instead of a kind application we were getting a type operator (@*). 2. Sometimes GHC printed kinds that were correct but hard to read. Should Either * Int be read as Either (*) Int or as (*) Either Int ? This depends on whether -XStarIsType is enabled, but it would be easier if we didn't have to check for the flag when reading the code. We can solve both problems by assigning (*) a different precedence. Note that Haskell98 kinds are not affected: ((* -> *) -> *) -> * does NOT become (((*) -> (*)) -> (*)) -> (*) The parentheses are added when (*) is used in a function argument position: F * * * becomes F (*) (*) (*) F A * B becomes F A (*) B Proxy * becomes Proxy (*) a * -> * becomes a (*) -> * - - - - - 70dd0e4b by Vladislav Zavialov at 2019-12-05T16:07:49-05:00 Parenthesize the * kind in TH.Ppr - - - - - a7a4efbf by Ben Gamari at 2019-12-05T16:07:49-05:00 rts/NonMovingSweep: Fix locking of new mutable list allocation Previously we used allocBlockOnNode_sync in nonmovingSweepMutLists despite the fact that we aren't in the GC and therefore the allocation spinlock isn't in use. This meant that sweep would end up spinning until the next minor GC, when the SM lock was moved away from the SM_MUTEX to the spinlock. This isn't a correctness issue but it sure isn't good for performance. Found thanks for Ward. Fixes #17539. - - - - - f171b358 by Matthias Braun at 2019-12-05T16:07:51-05:00 Fix typo in documentation of Base.hs. - - - - - 9897e8c8 by Gabor Greif at 2019-12-06T21:20:38-05:00 Implement pointer tagging for big families (#14373) Formerly we punted on these and evaluated constructors always got a tag of 1. We now cascade switches because we have to check the tag first and when it is MAX_PTR_TAG then get the precise tag from the info table and switch on that. The only technically tricky part is that the default case needs (logical) duplication. To do this we emit an extra label for it and branch to that from the second switch. This avoids duplicated codegen. Here's a simple example of the new code gen: data D = D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 On a 64-bit system previously all constructors would be tagged 1. With the new code gen D7 and D8 are tagged 7: [Lib.D7_con_entry() { ... {offset c1eu: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] [Lib.D8_con_entry() { ... {offset c1ez: // global R1 = R1 + 7; call (P64[Sp])(R1) args: 8, res: 0, upd: 8; } }] When switching we now look at the info table only when the tag is 7. For example, if we derive Enum for the type above, the Cmm looks like this: c2Le: _s2Js::P64 = R1; _c2Lq::P64 = _s2Js::P64 & 7; switch [1 .. 7] _c2Lq::P64 { case 1 : goto c2Lk; case 2 : goto c2Ll; case 3 : goto c2Lm; case 4 : goto c2Ln; case 5 : goto c2Lo; case 6 : goto c2Lp; case 7 : goto c2Lj; } // Read info table for tag c2Lj: _c2Lv::I64 = %MO_UU_Conv_W32_W64(I32[I64[_s2Js::P64 & (-8)] - 4]); if (_c2Lv::I64 != 6) goto c2Lu; else goto c2Lt; Generated Cmm sizes do not change too much, but binaries are very slightly larger, due to the fact that the new instructions are longer in encoded form. E.g. previously entry code for D8 above would be 00000000000001c0 <Lib_D8_con_info>: 1c0: 48 ff c3 inc %rbx 1c3: ff 65 00 jmpq *0x0(%rbp) With this patch 00000000000001d0 <Lib_D8_con_info>: 1d0: 48 83 c3 07 add $0x7,%rbx 1d4: ff 65 00 jmpq *0x0(%rbp) This is one byte longer. Secondly, reading info table directly and then switching is shorter _c1co: movq -1(%rbx),%rax movl -4(%rax),%eax // Switch on info table tag jmp *_n1d5(,%rax,8) than doing the same switch, and then for the tag 7 doing another switch: // When tag is 7 _c1ct: andq $-8,%rbx movq (%rbx),%rax movl -4(%rax),%eax // Switch on info table tag ... Some changes of binary sizes in actual programs: - In NoFib the worst case is 0.1% increase in benchmark "parser" (see NoFib results below). All programs get slightly larger. - Stage 2 compiler size does not change. - In "containers" (the library) size of all object files increases 0.0005%. Size of the test program "bitqueue-properties" increases 0.03%. nofib benchmarks kindly provided by Ömer (@osa1): NoFib Results ============= -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.0% 0.0% -0.0% -0.0% -0.0% CSD +0.0% 0.0% 0.0% +0.0% +0.0% FS +0.0% 0.0% 0.0% +0.0% 0.0% S +0.0% 0.0% -0.0% 0.0% 0.0% VS +0.0% 0.0% -0.0% +0.0% +0.0% VSD +0.0% 0.0% -0.0% +0.0% -0.0% VSM +0.0% 0.0% 0.0% 0.0% 0.0% anna +0.0% 0.0% +0.1% -0.9% -0.0% ansi +0.0% 0.0% -0.0% +0.0% +0.0% atom +0.0% 0.0% 0.0% 0.0% 0.0% awards +0.0% 0.0% -0.0% +0.0% 0.0% banner +0.0% 0.0% -0.0% +0.0% 0.0% bernouilli +0.0% 0.0% +0.0% +0.0% +0.0% binary-trees +0.0% 0.0% -0.0% -0.0% -0.0% boyer +0.0% 0.0% +0.0% 0.0% -0.0% boyer2 +0.0% 0.0% +0.0% 0.0% -0.0% bspt +0.0% 0.0% +0.0% +0.0% 0.0% cacheprof +0.0% 0.0% +0.1% -0.8% 0.0% calendar +0.0% 0.0% -0.0% +0.0% -0.0% cichelli +0.0% 0.0% +0.0% 0.0% 0.0% circsim +0.0% 0.0% -0.0% -0.1% -0.0% clausify +0.0% 0.0% +0.0% +0.0% 0.0% comp_lab_zift +0.0% 0.0% +0.0% 0.0% -0.0% compress +0.0% 0.0% +0.0% +0.0% 0.0% compress2 +0.0% 0.0% 0.0% 0.0% 0.0% constraints +0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 +0.0% 0.0% +0.0% 0.0% 0.0% cryptarithm2 +0.0% 0.0% +0.0% -0.0% 0.0% cse +0.0% 0.0% +0.0% +0.0% 0.0% digits-of-e1 +0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 +0.0% 0.0% +0.0% -0.0% -0.0% dom-lt +0.0% 0.0% +0.0% +0.0% 0.0% eliza +0.0% 0.0% -0.0% +0.0% 0.0% event +0.0% 0.0% -0.0% -0.0% -0.0% exact-reals +0.0% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.0% 0.0% -0.0% -0.0% -0.0% expert +0.0% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.0% 0.0% +0.0% 0.0% 0.0% fasta +0.0% 0.0% -0.0% -0.0% -0.0% fem +0.0% 0.0% +0.0% +0.0% +0.0% fft +0.0% 0.0% +0.0% -0.0% -0.0% fft2 +0.0% 0.0% +0.0% +0.0% +0.0% fibheaps +0.0% 0.0% +0.0% +0.0% 0.0% fish +0.0% 0.0% +0.0% +0.0% 0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.0% 0.0% +0.0% -0.0% +0.0% gamteb +0.0% 0.0% +0.0% -0.0% -0.0% gcd +0.0% 0.0% +0.0% +0.0% 0.0% gen_regexps +0.0% 0.0% +0.0% -0.0% -0.0% genfft +0.0% 0.0% -0.0% -0.0% -0.0% gg +0.0% 0.0% 0.0% -0.0% 0.0% grep +0.0% 0.0% +0.0% +0.0% +0.0% hidden +0.0% 0.0% +0.0% -0.0% -0.0% hpg +0.0% 0.0% +0.0% -0.1% -0.0% ida +0.0% 0.0% +0.0% -0.0% -0.0% infer +0.0% 0.0% -0.0% -0.0% -0.0% integer +0.0% 0.0% -0.0% -0.0% -0.0% integrate +0.0% 0.0% 0.0% +0.0% 0.0% k-nucleotide +0.0% 0.0% -0.0% -0.0% -0.0% kahan +0.0% 0.0% -0.0% -0.0% -0.0% knights +0.0% 0.0% +0.0% -0.0% -0.0% lambda +0.0% 0.0% +1.2% -6.1% -0.0% last-piece +0.0% 0.0% +0.0% -0.0% -0.0% lcss +0.0% 0.0% +0.0% -0.0% -0.0% life +0.0% 0.0% +0.0% -0.0% -0.0% lift +0.0% 0.0% +0.0% +0.0% 0.0% linear +0.0% 0.0% +0.0% +0.0% +0.0% listcompr +0.0% 0.0% -0.0% -0.0% -0.0% listcopy +0.0% 0.0% -0.0% -0.0% -0.0% maillist +0.0% 0.0% +0.0% -0.0% -0.0% mandel +0.0% 0.0% +0.0% +0.0% +0.0% mandel2 +0.0% 0.0% +0.0% +0.0% -0.0% mate +0.0% 0.0% +0.0% +0.0% +0.0% minimax +0.0% 0.0% -0.0% +0.0% -0.0% mkhprog +0.0% 0.0% +0.0% +0.0% +0.0% multiplier +0.0% 0.0% 0.0% +0.0% -0.0% n-body +0.0% 0.0% +0.0% -0.0% -0.0% nucleic2 +0.0% 0.0% +0.0% +0.0% -0.0% para +0.0% 0.0% +0.0% +0.0% +0.0% paraffins +0.0% 0.0% +0.0% +0.0% +0.0% parser +0.1% 0.0% +0.4% -1.7% -0.0% parstof +0.0% 0.0% -0.0% -0.0% -0.0% pic +0.0% 0.0% +0.0% 0.0% -0.0% pidigits +0.0% 0.0% -0.0% -0.0% -0.0% power +0.0% 0.0% +0.0% -0.0% -0.0% pretty +0.0% 0.0% +0.0% +0.0% +0.0% primes +0.0% 0.0% +0.0% 0.0% 0.0% primetest +0.0% 0.0% +0.0% +0.0% +0.0% prolog +0.0% 0.0% +0.0% +0.0% +0.0% puzzle +0.0% 0.0% +0.0% +0.0% +0.0% queens +0.0% 0.0% 0.0% +0.0% +0.0% reptile +0.0% 0.0% +0.0% +0.0% 0.0% reverse-complem +0.0% 0.0% -0.0% -0.0% -0.0% rewrite +0.0% 0.0% +0.0% 0.0% -0.0% rfib +0.0% 0.0% +0.0% +0.0% +0.0% rsa +0.0% 0.0% +0.0% +0.0% +0.0% scc +0.0% 0.0% +0.0% +0.0% +0.0% sched +0.0% 0.0% +0.0% +0.0% +0.0% scs +0.0% 0.0% +0.0% +0.0% 0.0% simple +0.0% 0.0% +0.0% +0.0% +0.0% solid +0.0% 0.0% +0.0% +0.0% 0.0% sorting +0.0% 0.0% +0.0% -0.0% 0.0% spectral-norm +0.0% 0.0% -0.0% -0.0% -0.0% sphere +0.0% 0.0% +0.0% -1.0% 0.0% symalg +0.0% 0.0% +0.0% +0.0% +0.0% tak +0.0% 0.0% +0.0% +0.0% +0.0% transform +0.0% 0.0% +0.4% -1.3% +0.0% treejoin +0.0% 0.0% +0.0% -0.0% 0.0% typecheck +0.0% 0.0% -0.0% +0.0% 0.0% veritas +0.0% 0.0% +0.0% -0.1% +0.0% wang +0.0% 0.0% +0.0% +0.0% +0.0% wave4main +0.0% 0.0% +0.0% 0.0% -0.0% wheel-sieve1 +0.0% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.0% 0.0% +0.0% +0.0% 0.0% x2n1 +0.0% 0.0% +0.0% +0.0% 0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -6.1% -0.0% Max +0.1% 0.0% +1.2% +0.0% +0.0% Geometric Mean +0.0% -0.0% +0.0% -0.1% -0.0% NoFib GC Results ================ -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim +0.0% 0.0% -0.0% -0.0% -0.0% constraints +0.0% 0.0% -0.0% 0.0% -0.0% fibheaps +0.0% 0.0% 0.0% -0.0% -0.0% fulsom +0.0% 0.0% 0.0% -0.6% -0.0% gc_bench +0.0% 0.0% 0.0% 0.0% -0.0% hash +0.0% 0.0% -0.0% -0.0% -0.0% lcss +0.0% 0.0% 0.0% -0.0% 0.0% mutstore1 +0.0% 0.0% 0.0% -0.0% -0.0% mutstore2 +0.0% 0.0% +0.0% -0.0% -0.0% power +0.0% 0.0% -0.0% 0.0% -0.0% spellcheck +0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.6% -0.0% Max +0.0% 0.0% +0.0% 0.0% 0.0% Geometric Mean +0.0% +0.0% +0.0% -0.1% +0.0% Fixes #14373 These performance regressions appear to be a fluke in CI. See the discussion in !1742 for details. Metric Increase: T6048 T12234 T12425 Naperian T12150 T5837 T13035 - - - - - ee07421f by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Work in progress on coercionLKind, coercionRKind This is a preliminary patch for #17515 - - - - - 0a4ca9eb by Simon Peyton Jones at 2019-12-06T21:21:14-05:00 Split up coercionKind This patch implements the idea in #17515, splitting `coercionKind` into: * `coercion{Left,Right}Kind`, which computes the left/right side of the pair * `coercionKind`, which computes the pair of coercible types This is reduces allocation since we frequently only need only one side of the pair. Specifically, we see the following improvements on x86-64 Debian 9: | test | new | old | relative chg. | | :------- | ---------: | ------------: | ------------: | | T5030 | 695537752 | 747641152.0 | -6.97% | | T5321Fun | 449315744 | 474009040.0 | -5.21% | | T9872a | 2611071400 | 2645040952.0 | -1.28% | | T9872c | 2957097904 | 2994260264.0 | -1.24% | | T12227 | 773435072 | 812367768.0 | -4.79% | | T12545 | 3142687224 | 3215714752.0 | -2.27% | | T14683 | 9392407664 | 9824775000.0 | -4.40% | Metric Decrease: T12545 T9872a T14683 T5030 T12227 T9872c T5321Fun T9872b - - - - - d46a72e1 by Gabor Greif at 2019-12-09T12:05:15-05:00 Fix comment typos The below is only necessary to fix the CI perf fluke that happened in 9897e8c8ef0b19a9571ef97a1d9bb050c1ee9121: ------------------------- Metric Decrease: T5837 T6048 T9020 T12425 T12234 T13035 T12150 Naperian ------------------------- - - - - - e3bba7e4 by Micha Wiedenmann at 2019-12-10T19:52:44-05:00 users guide: Motivation of DefaultSignatures - - - - - 843ceb38 by Ben Gamari at 2019-12-10T19:53:54-05:00 rts: Add a long form flag to enable the non-moving GC The old flag, `-xn`, was quite cryptic. Here we add `--nonmoving-gc` in addition. - - - - - 921d3238 by Ryan Scott at 2019-12-10T19:54:34-05:00 Ignore unary constraint tuples during typechecking (#17511) We deliberately avoid defining a magical `Unit%` class, for reasons that I have expounded upon in the newly added `Note [Ignore unary constraint tuples]` in `TcHsType`. However, a sneaky user could try to insert `Unit%` into their program by way of Template Haskell, leading to the interface-file error observed in #17511. To avoid this, any time we encounter a unary constraint tuple during typechecking, we drop the surrounding constraint tuple application. This is safe to do since `Unit% a` and `a` would be semantically equivalent (unlike other forms of unary tuples). Fixes #17511. - - - - - 436ec9f3 by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 2f6b434f by Ben Gamari at 2019-12-10T19:55:37-05:00 gitlab-ci: Move changelog linting logic to shell script Allowing it to be easily used locally. - - - - - 7a5a6e07 by Ben Gamari at 2019-12-10T19:56:25-05:00 base: Fix incorrect @since in GHC.Natural Fixes #17547. - - - - - 2bbfaf8a by Ben Gamari at 2019-12-10T19:57:01-05:00 hadrian: AArch64 supports the GHCi interpreter and SMP I'm not sure how this was omitted from the list of supported architectures. - - - - - 8f1ceb67 by John Ericson at 2019-12-10T19:57:39-05:00 Move Int# section of primops.txt.pp This matches the organization of the fixed-sized ones, and keeps each Int* next to its corresponding Word*. - - - - - 7a823b0f by John Ericson at 2019-12-10T19:57:39-05:00 Move Int64# and Word64# sections of primops.txt.pp This way it is next to the other fixed-sized ones. - - - - - 8dd9929a by Ben Gamari at 2019-12-10T19:58:19-05:00 testsuite: Add (broken) test for #17510 - - - - - 6e47a76a by Ben Gamari at 2019-12-10T19:58:59-05:00 Re-layout validate script This script was previously a whitespace nightmare. - - - - - f80c4a66 by Crazycolorz5 at 2019-12-11T14:12:17-05:00 rts: Specialize hashing at call site rather than in struct. Separate word and string hash tables on the type level, and do not store the hashing function. Thus when a different hash function is desire it is provided upon accessing the table. This is worst case the same as before the change, and in the majority of cases is better. Also mark the functions for aggressive inlining to improve performance. {F1686506} Reviewers: bgamari, erikd, simonmar Subscribers: rwbarton, thomie, carter GHC Trac Issues: #13165 Differential Revision: https://phabricator.haskell.org/D4889 - - - - - 2d1b9619 by Richard Eisenberg at 2019-12-11T14:12:55-05:00 Warn on inferred polymorphic recursion Silly users sometimes try to use visible dependent quantification and polymorphic recursion without a CUSK or SAK. This causes unexpected errors. So we now adjust expectations with a bit of helpful messaging. Closes #17541 and closes #17131. test cases: dependent/should_fail/T{17541{,b},17131} - - - - - 4dde485e by Oleg Grenrus at 2019-12-12T02:24:46-05:00 Add --show-unit-ids flag to ghc-pkg I only added it into --simple-output and ghc-pkg check output; there are probably other places where it can be adopted. - - - - - e6e1ec08 by Ben Gamari at 2019-12-12T02:25:33-05:00 testsuite: Simplify and clarify performance test baseline search The previous implementation was extremely complicated, seemingly to allow the local and CI namespaces to be searched incrementally. However, it's quite unclear why this is needed and moreover the implementation seems to have had quadratic runtime cost in the search depth(!). - - - - - 29c4609c by Ben Gamari at 2019-12-12T02:26:19-05:00 testsuite: Add test for #17549 - - - - - 9f0ee253 by Ben Gamari at 2019-12-12T02:26:56-05:00 gitlab-ci: Move -dwarf and -debug jobs to full-build stage This sacrifices some precision in favor of improving parallelism. - - - - - 7179b968 by Ben Gamari at 2019-12-12T02:27:34-05:00 Revert "rts: Drop redundant flags for libffi" This seems to have regressed builds using `--with-system-libffi` (#17520). This reverts commit 3ce18700f80a12c48a029b49c6201ad2410071bb. - - - - - cc7d5650 by Oleg Grenrus at 2019-12-16T10:20:56+02:00 Having no shake upper bound is irresposible Given that shake is far from "done" API wise, and is central component to the build system. - - - - - 9431f905 by Oleg Grenrus at 2019-12-16T10:55:50+02:00 Add index-state to hadrian/cabal.project Then one is freer to omit upper bounds, as we won't pick any new entries on Hackage while building hadrian itself. - - - - - 3e17a866 by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Remove dataConSig As suggested in #17291 - - - - - 75355fde by Krzysztof Gogolewski at 2019-12-16T19:31:44-05:00 Use "OrCoVar" functions less As described in #17291, we'd like to separate coercions and expressions in a more robust fashion. This is a small step in this direction. - `mkLocalId` now panicks on a covar. Calls where this was not the case were changed to `mkLocalIdOrCoVar`. - Don't use "OrCoVar" functions in places where we know the type is not a coercion. - - - - - f9686e13 by Richard Eisenberg at 2019-12-16T19:32:21-05:00 Do more validity checks for quantified constraints Close #17583. Test case: typecheck/should_fail/T17563 - - - - - af763765 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Fix Windows artifact collection Variable interpolation in gitlab-ci.yml apparently doesn't work. Sigh. - - - - - e6d4b902 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Debian 10 - - - - - 8ba650e9 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Allow debian 8 build to fail The python release shipped with deb8 (3.3) is too old for our testsuite driver. - - - - - ac25a3f6 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Use xz --threads on Alpine - - - - - cc628088 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Another approach for xz detection - - - - - 37d788ab by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Re-add release-x86_64-deb9 job Also eliminate some redundancy. - - - - - f8279138 by Ben Gamari at 2019-12-16T19:33:01-05:00 gitlab-ci: Drop redundant release-x86_64-linux-deb9 job - - - - - 8148ff06 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark cgrun057 as broken on ARMv7 Due to #17554. It's very surprising that this only occurs on ARMv7 but this is the only place I've seen this failure thusfar. - - - - - 85e5696d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark prog001 as fragile on ARMv7 Due to #17555. - - - - - a5f0aab0 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T10272 as broken on ARMv7 Due to #17556. - - - - - 1e6827c6 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T13825-debugger as broken on ARMv7 Due to #17557. - - - - - 7cef0b7d by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T14028 as broken on ARMv7 Due to #17558. - - - - - 6ea4eb4b by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Make ghc_built_by_llvm check more precise Previously it would hackily look at the flavour name to determine whether LLVM was used to build stage2 ghc. However, this didn't work at all with Hadrian and would miss cases like ARM where we use the LLVM backend by default. See #16087 for the motivation for why ghc_built_by_llvm is needed at all. This should catch one of the ARMv7 failures described in #17555. - - - - - c3e82bf7 by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark T5435_* tests as broken on ARM `T5435_v_asm_a`, `T5435_v_asm_b`, and `T5435_v_gcc` all fail on ARMv7. See #17559. - - - - - eb2aa851 by Ben Gamari at 2019-12-17T07:24:40-05:00 gitlab-ci: Don't allow armv7 jobs to fail - - - - - efc92216 by Ben Gamari at 2019-12-17T07:24:40-05:00 Revert "testsuite: Mark cgrun057 as broken on ARMv7" This reverts commit 6cfc47ec8a478e1751cb3e7338954da1853c3996. - - - - - 1d2bb9eb by Ben Gamari at 2019-12-17T07:24:40-05:00 testsuite: Mark print002 as fragile on ARM Due to #17557. Also accepting spurious performance change. Metric Decrease: T1969 - - - - - 41f4e4fb by Josh Meredith at 2019-12-17T07:25:17-05:00 Fix ambiguous occurence error when building Hadrian - - - - - 4374983a by Josh Meredith at 2019-12-17T07:25:17-05:00 Rename SphinxMode constructors - - - - - a8f7ecd5 by Josh Meredith at 2019-12-17T07:25:17-05:00 Use *Mode suffix instead of *M - - - - - 58655b9d by Sylvain Henry at 2019-12-18T13:43:37+01:00 Add GHC-API logging hooks * Add 'dumpAction' hook to DynFlags. It allows GHC API users to catch dumped intermediate codes and information. The format of the dump (Core, Stg, raw text, etc.) is now reported allowing easier automatic handling. * Add 'traceAction' hook to DynFlags. Some dumps go through the trace mechanism (for instance unfoldings that have been considered for inlining). This is problematic because: 1) dumps aren't written into files even with -ddump-to-file on 2) dumps are written on stdout even with GHC API 3) in this specific case, dumping depends on unsafe globally stored DynFlags which is bad for GHC API users We introduce 'traceAction' hook which allows GHC API to catch those traces and to avoid using globally stored DynFlags. * Avoid dumping empty logs via dumpAction/traceAction (but still write empty files to keep the existing behavior) - - - - - fad866e0 by Moritz Kiefer at 2019-12-19T11:15:39-05:00 Avoid race condition in hDuplicateTo In our codebase we have some code along the lines of ``` newStdout <- hDuplicate stdout stderr `hDuplicateTo` stdout ``` to avoid stray `putStrLn`s from corrupting a protocol (LSP) that is run over stdout. On CI we have seen a bunch of issues where `dup2` returned `EBUSY` so this fails with `ResourceExhausted` in Haskell. I’ve spent some time looking at the docs for `dup2` and the code in `base` and afaict the following race condition is being triggered here: 1. The user calls `hDuplicateTo stderr stdout`. 2. `hDuplicateTo` calls `hClose_help stdout_`, this closes the file handle for stdout. 3. The file handle for stdout is now free, so another thread allocating a file might get stdout. 4. If `dup2` is called while `stdout` (now pointing to something else) is half-open, it returns EBUSY. I think there might actually be an even worse case where `dup2` is run after FD 1 is fully open again. In that case, you will end up not just redirecting the original stdout to stderr but also the whatever resulted in that file handle being allocated. As far as I can tell, `dup2` takes care of closing the file handle itself so there is no reason to do this in `hDuplicateTo`. So this PR replaces the call to `hClose_help` by the only part of `hClose_help` that we actually care about, namely, `flushWriteBuffer`. I tested this on our codebase fairly extensively and haven’t been able to reproduce the issue with this patch. - - - - - 0c114c65 by Sylvain Henry at 2019-12-19T11:16:17-05:00 Handle large ARR_WORDS in heap census (fix #17572) We can do a heap census with a non-profiling RTS. With a non-profiling RTS we don't zero superfluous bytes of shrunk arrays hence a need to handle the case specifically to avoid a crash. Revert part of a586b33f8e8ad60b5c5ef3501c89e9b71794bbed - - - - - 1a0d1a65 by John Ericson at 2019-12-20T10:50:22-05:00 Deduplicate copied monad failure handler code - - - - - 70e56b27 by Ryan Scott at 2019-12-20T10:50:57-05:00 lookupBindGroupOcc: recommend names in the same namespace (#17593) Previously, `lookupBindGroupOcc`'s error message would recommend all similar names in scope, regardless of whether they were type constructors, data constructors, or functions, leading to the confusion witnessed in #17593. This is easily fixed by only recommending names in the same namespace, using the `nameSpacesRelated` function. Fixes #17593. - - - - - 3c12355e by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN Include header file `ghcautoconf.h` where the CPP macro `WORDS_BIGENDIAN` is defined. This finally fixes #17337 (in conjunction with commit 6c59cc71dc). - - - - - 11f8eef5 by Stefan Schulze Frielinghaus at 2019-12-24T01:03:44-05:00 fixup! Fix endian handling w.r.t. CPP macro WORDS_BIGENDIAN - - - - - 40327b03 by Sylvain Henry at 2019-12-24T01:04:24-05:00 Remove outdated comment - - - - - aeea92ef by Sylvain Henry at 2019-12-25T19:23:54-05:00 Switch to ReadTheDocs theme for the user-guide - - - - - 26493eab by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix copy-paste error in comment - - - - - 776df719 by Gabor Greif at 2019-12-25T19:24:32-05:00 Fix comment about minimal gcc version to be consistent what FP_GCC_VERSION requires - - - - - 3b17114d by Ömer Sinan Ağacan at 2019-12-26T14:09:11-05:00 Minor refactor in ghc.cabal.in: - Remove outdated comments - Move cutils.c from parser to cbits - Remove unused cutils.h - - - - - 334290b6 by Ryan Scott at 2019-12-26T14:09:48-05:00 Replace panic/notHandled with noExtCon in DsMeta There are many spots in `DsMeta` where `panic` or `notHandled` is used after pattern-matching on a TTG extension constructor. This is overkill, however, as using `noExtCon` would work just as well. This patch switches out these panics for `noExtCon`. - - - - - 68252aa3 by Ben Gamari at 2019-12-27T15:11:38-05:00 testsuite: Skip T17499 when built against integer-simple Since it routinely times out in CI. - - - - - 0c51aeeb by Gabor Greif at 2019-12-27T15:12:17-05:00 suppress popup dialog about missing Xcode at configure tested with `bash` and `zsh`. - - - - - 8d76bcc2 by Gabor Greif at 2019-12-27T15:12:17-05:00 while at it rename XCode to the official Xcode - - - - - 47a68205 by Ben Gamari at 2019-12-27T15:12:55-05:00 testsuite: Mark cgrun057 as fragile on ARM As reported in #17554. Only marking on ARM for now although there is evidence to suggest that the issue may occur on other platforms as well. - - - - - d03dec8f by Gabor Greif at 2019-12-27T15:13:32-05:00 use shell variable CcLlvmBackend for test Previously we used `AC_DEFINE`d variable `CC_LLVM_BACKEND` which has an empty shell expansion. - - - - - 2528e684 by Ben Gamari at 2019-12-30T06:51:32-05:00 driver: Include debug level in the recompilation check hash Fixes #17586. - - - - - f14bb50b by Ben Gamari at 2019-12-30T06:52:09-05:00 rts: Ensure that nonmoving gc isn't used with profiling - - - - - b426de37 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Ensure that entry labels don't have predecessors The LLVM IR forbids the entry label of a procedure from having any predecessors. In the case of a simple looping function the LLVM code generator broke this invariant, as noted in #17589. Fix this by moving the function prologue to its own basic block, as suggested by @kavon in #11649. Fixes #11649 and #17589. - - - - - 613f7265 by Ben Gamari at 2019-12-30T06:52:45-05:00 llvmGen: Drop old fix for #11649 This was a hack which is no longer necessary now since we introduce a dedicated entry block for each procedure. - - - - - fdeffa5e by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Error on invalid --numa flags Previously things like `+RTS --numa-debug` would enable NUMA support, despite being an invalid flag. - - - - - 9ce3ba68 by Ben Gamari at 2019-12-30T06:53:23-05:00 rts: Fix --debug-numa mode under Docker As noted in #17606, Docker disallows the get_mempolicy syscall by default. This caused numerous tests to fail under CI in the `debug_numa` way. Avoid this by disabling the NUMA probing logic when --debug-numa is in use, instead setting n_numa_nodes in RtsFlags.c. Fixes #17606. - - - - - 5baa2a43 by Ben Gamari at 2019-12-30T06:54:01-05:00 testsuite: Disable derefnull when built with LLVM LLVM does not guarantee any particular semantics when dereferencing null pointers. Consequently, this test actually passes when built with the LLVM backend. - - - - - bd544d3d by Ben Gamari at 2019-12-30T06:54:38-05:00 hadrian: Track hash of Cabal Setup builder arguments Lest we fail to rebuild when they change. Fixes #17611. - - - - - 6e2c495e by Ben Gamari at 2019-12-30T06:55:19-05:00 TcIface: Fix inverted logic in typechecking of source ticks Previously we would throw away source ticks when the debug level was non-zero. This is precisely the opposite of what was intended. Fixes #17616. Metric Decrease: T13056 T9020 T9961 T12425 - - - - - 7fad387d by Ben Gamari at 2019-12-30T06:55:55-05:00 perf_notes: Add --zero-y argument This makes it easier to see the true magnitude of fluctuations. Also do some house-keeping in the argument parsing department. - - - - - 0d42b287 by Ben Gamari at 2019-12-30T06:55:55-05:00 testsuite: Enlarge acceptance window for T1969 As noted in #17624, it's quite unstable, especially, for some reason, on i386 and armv7 (something about 32-bit platforms perhaps?). Metric Increase: T1969 - - - - - eb608235 by Sylvain Henry at 2019-12-31T14:22:32-05:00 Module hierarchy (#13009): Stg - - - - - d710fd66 by Vladislav Zavialov at 2019-12-31T14:23:10-05:00 Testsuite: update some Haddock tests Fixed tests: * haddockA039: added to all.T * haddockE004: replaced with T17561 (marked as expect_broken) New tests: * haddockA040: deriving clause for a data instance * haddockA041: haddock and CPP #include - - - - - 859ebdd4 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add "-Iw" RTS flag for minimum wait between idle GCs (#11134) - - - - - dd4b6551 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Add additional Note explaining the -Iw flag - - - - - c4279ff1 by Kevin Buhr at 2019-12-31T23:44:39-05:00 Fix some sloppy indentation - - - - - b84c09d5 by Ömer Sinan Ağacan at 2019-12-31T23:45:19-05:00 Tweak Cmm dumps to avoid generating sections for empty groups When dumping Cmm groups check if the group is empty, to avoid generating empty sections in dump files like ==================== Output Cmm ==================== [] Also fixes a few bad indentation in the code around changes. - - - - - b2e0323f by Gabor Greif at 2020-01-03T21:22:36-05:00 Simplify mrStr - - - - - 3c9dc06b by Brian Wignall at 2020-01-04T15:55:06-05:00 Fix typos, via a Levenshtein-style corrector - - - - - d561c8f6 by Sylvain Henry at 2020-01-04T15:55:46-05:00 Add Cmm related hooks * stgToCmm hook * cmmToRawCmm hook These hooks are used by Asterius and could be useful to other clients of the GHC API. It increases the Parser dependencies (test CountParserDeps) to 184. It's still less than 200 which was the initial request (cf https://mail.haskell.org/pipermail/ghc-devs/2019-September/018122.html) so I think it's ok to merge this. - - - - - ae6b6276 by Oleg Grenrus at 2020-01-04T15:56:22-05:00 Update to Cabal submodule to v3.2.0.0-alpha3 Metric Increase: haddock.Cabal - - - - - 073f7cfd by Vladislav Zavialov at 2020-01-04T15:56:59-05:00 Add lexerDbg to dump the tokens fed to the parser This a small utility function that comes in handy when debugging the lexer and the parser. - - - - - 558d4d4a by Sylvain Henry at 2020-01-04T15:57:38-05:00 Split integerGmpInternals test in several parts This is to prepare for ghc-bignum which implements some but not all of gmp functions. - - - - - 4056b966 by Ben Gamari at 2020-01-04T15:58:15-05:00 testsuite: Mark cgrun057 as fragile on all platforms I have seen this fail both on x86-64/Debian 9 and armv7/Debian 9 See #17554. - - - - - 5ffea0c6 by Tamar Christina at 2020-01-06T18:38:37-05:00 Fix overflow. - - - - - 99a9f51b by Sylvain Henry at 2020-01-06T18:39:22-05:00 Module hierarchy: Iface (cf #13009) - - - - - 7aa4a061 by Ben Gamari at 2020-01-07T13:11:48-05:00 configure: Only check GCC version if CC is GCC Also refactor FP_GCC_EXTRA_FLAGS in a few ways: * We no longer support compilers which lack support for -fno-builtin and -fwrapv so remove the condition on GccVersion * These flags are only necessary when using the via-C backend so make them conditional on Unregisterised. Fixes #15742. - - - - - 0805ed7e by John Ericson at 2020-01-07T13:12:25-05:00 Use non-empty lists to remove partiality in matching code - - - - - 7844f3a8 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Mark T17073 as broken on Windows Due to #17607. - - - - - acf40cae by Ben Gamari at 2020-01-07T13:13:02-05:00 gitlab-ci: Disallow Windows from failing - - - - - 34bc02c7 by Ben Gamari at 2020-01-07T13:13:02-05:00 configure: Find Python3 for testsuite In addition, we prefer the Mingw64 Python distribution on Windows due to #17483. - - - - - e35fe8d5 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Fix Windows platform test Previously we used platform.system() and while this worked fine (e.g. returned `Windows`, as expected) locally under both msys and MingW64 Python distributions, it inexplicably returned `MINGW64_NT-10.0` under MingW64 Python on CI. It seems os.name is more reliable so we now use that instead.. - - - - - 48ef6217 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Rename push-test-metrics.sh to test-metrics.sh Refactoring to follow. - - - - - 2234fa92 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Pull test metrics before running testsuite Otherwise the testsuite driver may not have an up-to-date baseline. - - - - - 1ca9adbc by Sylvain Henry at 2020-01-07T13:14:18-05:00 Remove `parallel` check from configure.ac `parallel` is no longer a submodule since 3cb063c805ec841ca33b8371ef8aba9329221b6c - - - - - b69a3460 by Ryan Scott at 2020-01-07T13:14:57-05:00 Monomorphize HsModule to GhcPs (#17642) Analyzing the call sites for `HsModule` reveals that it is only ever used with parsed code (i.e., `GhcPs`). This simplifies `HsModule` by concretizing its `pass` parameter to always be `GhcPs`. Fixes #17642. - - - - - d491a679 by Sylvain Henry at 2020-01-08T06:16:31-05:00 Module hierarchy: Renamer (cf #13009) - - - - - d589410f by Ben Gamari at 2020-01-08T06:17:09-05:00 Bump haskeline submodule to 0.8.0.1 (cherry picked from commit feb3b955402d53c3875dd7a9a39f322827e5bd69) - - - - - 923a1272 by Ryan Scott at 2020-01-08T06:17:47-05:00 Print Core type applications with no whitespace after @ (#17643) This brings the pretty-printer for Core in line with how visible type applications are normally printed: namely, with no whitespace after the `@` character (i.e., `f @a` instead of `f @ a`). While I'm in town, I also give the same treatment to type abstractions (i.e., `\(@a)` instead of `\(@ a)`) and coercion applications (i.e., `f @~x` instead of `f @~ x`). Fixes #17643. - - - - - 49f83a0d by Adam Sandberg Eriksson at 2020-01-12T21:28:09-05:00 improve docs for HeaderInfo.getImports [skip ci] - - - - - 9129210f by Matthew Pickering at 2020-01-12T21:28:47-05:00 Overloaded Quotation Brackets (#246) This patch implements overloaded quotation brackets which generalise the desugaring of all quotation forms in terms of a new minimal interface. The main change is that a quotation, for example, [e| 5 |], will now have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass contains a single method for generating new names which is used when desugaring binding structures. The return type of functions from the `Lift` type class, `lift` and `liftTyped` have been restricted to `forall m . Quote m => m Exp` rather than returning a result in a Q monad. More details about the feature can be read in the GHC proposal. https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst - - - - - 350e2b78 by Richard Eisenberg at 2020-01-12T21:29:27-05:00 Don't zap to Any; error instead This changes GHC's treatment of so-called Naughty Quantification Candidates to issue errors, instead of zapping to Any. Close #16775. No new test cases, because existing ones cover this well. - - - - - 0b5ddc7f by Brian Wignall at 2020-01-12T21:30:08-05:00 Fix more typos, via an improved Levenshtein-style corrector - - - - - f732dbec by Ben Gamari at 2020-01-12T21:30:49-05:00 gitlab-ci: Retain bindists used by head.hackage for longer Previously we would keep them for two weeks. However, on the stable branches two weeks can easily elapse with no pushes. - - - - - c8636da5 by Sylvain Henry at 2020-01-12T21:31:30-05:00 Fix LANG=C for readelf invocation in T14999 The test fails when used with LANG=fr_FR.UTF-8 - - - - - 077a88de by Jean-Baptiste Mazon at 2020-01-12T21:32:08-05:00 users-guide/debug-info: typo “behivior” - - - - - 61916c5d by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Add comments about TH levels - - - - - 1fd766ca by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Comments about constraint floating - - - - - de01427e by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Minor refactor around quantified constraints This patch clarifies a dark corner of quantified constraints. * See Note [Yukky eq_sel for a HoleDest] in TcSMonad * Minor refactor, breaking out new function TcInteract.doTopReactEqPred - - - - - 30be3bf1 by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Comments in TcHsType - - - - - c5977d4d by Sebastian Graf at 2020-01-16T05:58:58-05:00 Better documentation for mkEtaWW [skip ci] So that hopefully I understand it faster next time. Also got rid of the confusing `orig_expr`, which makes the call site in `etaExpand` look out of sync with the passed `n` (which is not the original `n`). - - - - - 22c0bdc3 by John Ericson at 2020-01-16T05:59:37-05:00 Handle TagToEnum in the same big case as the other primops Before, it was a panic because it was handled above. But there must have been an error in my reasoning (another caller?) because #17442 reported the panic was hit. But, rather than figuring out what happened, I can just make it impossible by construction. By adding just a bit more bureaucracy in the return types, I can handle TagToEnum in the same case as all the others, so the big case is is now total, and the panic is removed. Fixes #17442 - - - - - ee5d63f4 by John Ericson at 2020-01-16T05:59:37-05:00 Get rid of OpDest `OpDest` was basically a defunctionalization. Just turn the code that cased on it into those functions, and call them directly. - - - - - 1ff55226 by John Ericson at 2020-01-16T06:00:16-05:00 Remove special case case of bool during STG -> C-- Allow removing the no longer needed cgPrimOp, getting rid of a small a small layer violation too. Change which made the special case no longer needed was #6135 / 6579a6c73082387f82b994305011f011d9d8382b, which dates back to 2013, making me feel better. - - - - - f416fe64 by Adam Wespiser at 2020-01-16T06:00:53-05:00 replace dead html link (fixes #17661) - - - - - f6bf2ce8 by Sebastian Graf at 2020-01-16T06:01:32-05:00 Revert "`exprOkForSpeculation` for Note [IO hack in the demand analyser]" This reverts commit ce64b397777408731c6dd3f5c55ea8415f9f565b on the grounds of the regression it would introduce in a couple of packages. Fixes #17653. Also undoes a slight metric increase in #13701 introduced by that commit that we didn't see prior to !1983. Metric Decrease: T13701 - - - - - a71323ff by Ben Gamari at 2020-01-17T08:43:16-05:00 gitlab-ci: Don't FORCE_SYMLINKS on Windows Not all runners have symlink permissions enabled. - - - - - 0499e3bc by Ömer Sinan Ağacan at 2020-01-20T15:31:33-05:00 Fix +RTS -Z flag documentation Stack squeezing is done on context switch, not on GC or stack overflow. Fix the documentation. Fixes #17685 [ci skip] - - - - - a661df91 by Ömer Sinan Ağacan at 2020-01-20T15:32:13-05:00 Document Stg.FVs module Fixes #17662 [ci skip] - - - - - db24e480 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Don't trash STG registers Fixes #13904. - - - - - f3d7fdb3 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix typo in readnone attribute - - - - - 442751c6 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Add lower-expect to the -O0 optimisation set @kavon says that this will improve block layout for stack checks. - - - - - e90ecc93 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix #14251 Fixes the calling convention for functions passing raw SSE-register values by adding padding as needed to get the values in the right registers. This problem cropped up when some args were unused an dropped from the live list. This folds together 2e23e1c7de01c92b038e55ce53d11bf9db993dd4 and 73273be476a8cc6c13368660b042b3b0614fd928 previously from @kavon. Metric Increase: T12707 ManyConstructors - - - - - 66e511a4 by Ben Gamari at 2020-01-20T15:33:28-05:00 testsuite: Preserve more information in framework failures Namely print the entire exception in hopes that this will help track down #17649. - - - - - b62b8cea by Ömer Sinan Ağacan at 2020-01-20T15:34:06-05:00 Remove deprecated -smp flag It was deprecated in 2012 with 46258b40 - - - - - 0c04a86a by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Reenable submodule linter - - - - - 2bfabd22 by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Allow submodule cleaning to fail on Windows Currently CI is inexplicably failing with ``` $ git submodule foreach git clean -xdf fatal: not a git repository: libffi-tarballs/../.git/modules/libffi-tarballs ``` I have no idea how this working tree got into such a state but we do need to fail more gracefully when it happens. Consequently, we allow the cleaning step to fail. - - - - - 14bced99 by Xavier Denis at 2020-01-20T15:35:21-05:00 Put the docs for :instances in alphabetical position - - - - - 7e0bb82b by Ben Gamari at 2020-01-20T15:35:57-05:00 Add missing Note [Improvement from Ground Wanteds] Closes #17659. - - - - - 17e43a7c by Ben Gamari at 2020-01-20T15:36:32-05:00 unregisterised: Fix declaration for stg_NO_FINALIZER Previously it had a redundant _entry suffix. We never noticed this previously presumably because we never generated references to it (however hard to believe this may be). However, it did start failing in !1304. - - - - - 3dae006f by PHO at 2020-01-20T15:37:08-05:00 Avoid ./configure failure on NetBSD - - - - - 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - d0dd6f0e by Matthew Pickering at 2020-04-19T16:01:09+01:00 rts: Implement ghc-debug API There are four components to this patch which make it possible to implement `ghc-debug`. 1. Add four new functions to the RtsAPI. * rts_pause and rts_unpause allow an external process to completely pause and unpause the RTS. * rts_listThreads and rts_listMiscRoots are used to find the current roots of the garbage collector. These changes also mean that `Task.h` is exposed to the user. 2. Generalise the `ghc-heap` API so that raw `Word`s can be returned rather than actual objects. This is necessary when trying to decode closures on an external process because the pointers in such closures are correct for the internal rather than external process. If you used the previous API then you would get a segfault as the garbage collector would try to traverse into these nonsensical branches. ``` -- before getClosureData :: a -> IO Closure -- after getClosureDataX :: (forall c . c -> IO (Ptr StgInfoTable, [Word], [b])) -> a -> IO (GenClosure b) ``` For the normal case `b` is instantiated to `Box`, which contains a pointer to a heap object. ``` data Box = Box a -- GenClosure Box ``` For `ghc-debug` we instead just take the word of the address as we have to explicitly interpret it on the external process. ``` GenClosure Word ``` 3. Support for decoding `TSO` and `STACK` closures is partially implemented. There is still quite a bit of work to do to finish both but these at least allow us to make some more progress. 4. findPtr is generalised to take a callback argument. This means that its result can be communicated to the debugger rather than just printing out the result. The debugger has a function which invokes `findPtr` and passes a callback which sends the result over a socket. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 19 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - + .gitlab/linters/check-changelogs.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/push-test-metrics.sh - + .gitlab/test-metrics.sh - − .gitlab/win32-init.sh - .gitmodules - CODEOWNERS - HACKING.md - aclocal.m4 - boot - + compiler/GHC.hs - + compiler/GHC/Builtin/Names.hs - + compiler/GHC/Builtin/Names.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c5f8d4741503a043ddfe5fefeac5e984a0f3062f...d0dd6f0e7301f15d0f3e0fcc83b2cb143c29a6a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c5f8d4741503a043ddfe5fefeac5e984a0f3062f...d0dd6f0e7301f15d0f3e0fcc83b2cb143c29a6a2 You're receiving 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 19 15:09:51 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 11:09:51 -0400 Subject: [Git][ghc/ghc][wip/with2-primop] 2 commits: CorePrep: Admit nested runRW# applications Message-ID: <5e9c69bf26bd4_61673f8199536d945735719@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/with2-primop at Glasgow Haskell Compiler / GHC Commits: 4fd166ae by Ben Gamari at 2020-04-19T04:50:47+00:00 CorePrep: Admit nested runRW# applications We can then end up with applications of the form runRW# (\s s' -> ...) s'' Which have a higher apparent arity than CorePrep previously expected for runRW#. TODO: Do same for keepAlive# - - - - - 88a9a43b by Ben Gamari at 2020-04-19T15:09:24+00:00 SetLevels: Don't float out of runRW# and keepAlive# apps - - - - - 2 changed files: - compiler/GHC/Core/Op/SetLevels.hs - compiler/GHC/CoreToStg/Prep.hs Changes: ===================================== compiler/GHC/Core/Op/SetLevels.hs ===================================== @@ -91,10 +91,12 @@ import GHC.Types.Demand ( StrictSig, Demand, isStrictDmd, splitStrictSig, import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Types.Name ( getOccName, mkSystemVarName ) import GHC.Types.Name.Occurrence ( occNameString ) +import GHC.Types.Unique ( hasKey ) import GHC.Core.Type ( Type, mkLamTypes, splitTyConApp_maybe, tyCoVarsOfType , mightBeUnliftedType, closeOverKindsDSet ) import GHC.Types.Basic ( Arity, RecFlag(..), isRec ) import GHC.Core.DataCon ( dataConOrigResTy ) +import PrelNames ( runRWKey, keepAliveIdKey ) import TysWiredIn import GHC.Types.Unique.Supply import Util @@ -399,8 +401,12 @@ lvlNonTailExpr env expr lvlApp :: LevelEnv -> CoreExprWithFVs -> (CoreExprWithFVs, [CoreExprWithFVs]) -- Input application - -> LvlM LevelledExpr -- Result expression + -> LvlM LevelledExpr -- Result expression lvlApp env orig_expr ((_,AnnVar fn), args) + | fn `hasKey` runRWKey || fn `hasKey` keepAliveIdKey + = do { args' <- mapM (lvlExpr env) args + ; return (foldl' App (lookupVar env fn) args') } + | floatOverSat env -- See Note [Floating over-saturated applications] , arity > 0 , arity < n_val_args ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -847,14 +847,18 @@ cpeApp top_env expr -- rather than the far superior "f x y". Test case is par01. = let (terminal, args', depth') = collect_args arg in cpe_app env terminal (args' ++ args) (depth + depth' - 1) - cpe_app env (Var f) [CpeApp _runtimeRep at Type{}, CpeApp _type at Type{}, CpeApp arg] 1 + cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) n | 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 + , n >= 1 -- 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 [] 0 - _ -> cpe_app env arg [CpeApp (Var realWorldPrimId)] 1 + Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest (n-2) + _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) (n-1) + -- TODO: What about casts? cpe_app env (Var f) args n | f `hasKey` runRWKey View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae6dae6a6c4d668c2639764bee1e0bbf42c646d1...88a9a43b6a9d5c17f239fd13e72aa01937d7fade -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae6dae6a6c4d668c2639764bee1e0bbf42c646d1...88a9a43b6a9d5c17f239fd13e72aa01937d7fade You're receiving 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 19 16:00:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 12:00:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/runRW Message-ID: <5e9c7581907fb_61673f81ef22dee4574097c@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/runRW at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/runRW You're receiving 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 19 19:28:11 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 15:28:11 -0400 Subject: [Git][ghc/ghc][wip/runRW] Fix warnings Message-ID: <5e9ca64bd0d13_61673f8199536d9457591d6@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: d07ff71d by Ben Gamari at 2020-04-19T15:27:57-04:00 Fix warnings - - - - - 3 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Stg/Lint.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -44,7 +44,6 @@ import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Id.Info import TysWiredIn -import TysPrim ( realWorldStatePrimTy ) import GHC.Core.DataCon import GHC.Types.Basic import GHC.Types.Module @@ -843,7 +842,7 @@ cpeApp top_env expr _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) (n-1) -- TODO: What about casts? - cpe_app env (Var f) args n + cpe_app _env (Var f) args n | f `hasKey` runRWKey = pprPanic "cpe_app(runRW#)" (ppr args $$ ppr n) ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -490,7 +490,7 @@ mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg Var v1 | isInternalName (idName v1) -> v1 -- Note [Desugaring seq], points (2) and (3) _ -> mkWildValBinder ty1 -mkCoreAppDs _ e@(Var f `App` Type r `App` Type ty1) arg +mkCoreAppDs _ e@(Var f `App` Type _rep `App` Type ty1) arg | f `hasKey` runRWKey = e `App` etaExpand 1 arg ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -54,7 +54,6 @@ import ErrUtils ( MsgDoc, Severity(..), mkLocMessage ) import GHC.Core.Type import GHC.Types.RepType import GHC.Types.SrcLoc -import GHC.Types.Unique ( hasKey ) import Outputable import GHC.Types.Module ( Module ) import qualified ErrUtils as Err View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d07ff71dfb3826bc39b54da75e4fcbeaedd05a61 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d07ff71dfb3826bc39b54da75e4fcbeaedd05a61 You're receiving 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 19 21:38:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 17:38:30 -0400 Subject: [Git][ghc/ghc][wip/runRW] Fix warnings Message-ID: <5e9cc4d63e70a_6167134ebbc45763223@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: b290f5b3 by Ben Gamari at 2020-04-19T17:38:21-04:00 Fix warnings - - - - - 3 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Stg/Lint.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -44,7 +44,6 @@ import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Id.Info import TysWiredIn -import TysPrim ( realWorldStatePrimTy ) import GHC.Core.DataCon import GHC.Types.Basic import GHC.Types.Module @@ -843,7 +842,7 @@ cpeApp top_env expr _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) (n-1) -- TODO: What about casts? - cpe_app env (Var f) args n + cpe_app _env (Var f) args n | f `hasKey` runRWKey = pprPanic "cpe_app(runRW#)" (ppr args $$ ppr n) ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -490,7 +490,7 @@ mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg Var v1 | isInternalName (idName v1) -> v1 -- Note [Desugaring seq], points (2) and (3) _ -> mkWildValBinder ty1 -mkCoreAppDs _ e@(Var f `App` Type r `App` Type ty1) arg +mkCoreAppDs _ e@(Var f `App` Type _rep `App` Type _ty1) arg | f `hasKey` runRWKey = e `App` etaExpand 1 arg ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -54,7 +54,6 @@ import ErrUtils ( MsgDoc, Severity(..), mkLocMessage ) import GHC.Core.Type import GHC.Types.RepType import GHC.Types.SrcLoc -import GHC.Types.Unique ( hasKey ) import Outputable import GHC.Types.Module ( Module ) import qualified ErrUtils as Err View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b290f5b31e1de4b77fa61a4447ad60efe6807d90 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b290f5b31e1de4b77fa61a4447ad60efe6807d90 You're receiving 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 19 22:38:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 18:38:48 -0400 Subject: [Git][ghc/ghc][wip/runRW] 40 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5e9cd2f846dbd_616765c7a2857648e3@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 56209c6a by Ben Gamari at 2020-04-19T18:30:34-04:00 runRW - - - - - 64c3afa4 by Ben Gamari at 2020-04-19T18:30:34-04:00 genprimopcode: Add a second levity-polymorphic tyvar - - - - - 38dea3ab by Ben Gamari at 2020-04-19T18:30:34-04:00 XXX: Relax Note [Join points are less general than the paper] - - - - - 16a2df9b by Ben Gamari at 2020-04-19T18:30:34-04:00 XXX: Don't apply Note [dodgy unsafeCoerce 1] to join points - - - - - f0bc4ba4 by Ben Gamari at 2020-04-19T18:30:34-04:00 codeGen: A bit of debugging output - - - - - 55a81334 by Ben Gamari at 2020-04-19T18:30:34-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 77212418 by Ben Gamari at 2020-04-19T18:31:31-04:00 Fix warnings - - - - - 975f4ef7 by Ben Gamari at 2020-04-19T18:38:37-04:00 Fix rebase issues - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/DataCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b290f5b31e1de4b77fa61a4447ad60efe6807d90...975f4ef765e9cafe05edcc754c9294dd244b451e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b290f5b31e1de4b77fa61a4447ad60efe6807d90...975f4ef765e9cafe05edcc754c9294dd244b451e You're receiving 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 19 22:40:54 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 18:40:54 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fix-hadrian-ghci Message-ID: <5e9cd376de0de_61673f81ef22dee457652eb@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/fix-hadrian-ghci at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix-hadrian-ghci You're receiving 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 19 22:51:37 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 19 Apr 2020 18:51:37 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/keepAlive Message-ID: <5e9cd5f96d886_6167865d29c5769324@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/keepAlive at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/keepAlive You're receiving 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 20 02:26:29 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 19 Apr 2020 22:26:29 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Add missing addInScope call for letrec binders in OccurAnal Message-ID: <5e9d0855db7fd_61673f8198ee100c57753ca@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - ed8c86dc by Shayne Fletcher at 2020-04-19T22:26:21-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - 72fbb131 by Simon Peyton Jones at 2020-04-19T22:26:22-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - 7 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Tc/TyCl/Instance.hs - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/typecheck/should_compile/T18036.hs - + testsuite/tests/typecheck/should_compile/T18036a.hs - + testsuite/tests/typecheck/should_compile/T18036a.stderr - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -843,7 +843,7 @@ occAnalNonRecBind env lvl imp_rule_edges bndr rhs body_usage occAnalRecBind :: OccEnv -> TopLevelFlag -> ImpRuleEdges -> [(Var,CoreExpr)] -> UsageDetails -> (UsageDetails, [CoreBind]) occAnalRecBind env lvl imp_rule_edges pairs body_usage - = foldr (occAnalRec env lvl) (body_usage, []) sccs + = foldr (occAnalRec rhs_env lvl) (body_usage, []) sccs -- For a recursive group, we -- * occ-analyse all the RHSs -- * compute strongly-connected components @@ -856,9 +856,11 @@ occAnalRecBind env lvl imp_rule_edges pairs body_usage nodes :: [LetrecNode] nodes = {-# SCC "occAnalBind.assoc" #-} - map (makeNode env imp_rule_edges bndr_set) pairs + map (makeNode rhs_env imp_rule_edges bndr_set) pairs - bndr_set = mkVarSet (map fst pairs) + bndrs = map fst pairs + bndr_set = mkVarSet bndrs + rhs_env = env `addInScope` bndrs {- Note [Unfoldings and join points] ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1719,19 +1719,26 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind | Just hs_sig_ty <- hs_sig_fn sel_name -- There is a signature in the instance -- See Note [Instance method signatures] - = do { let ctxt = FunSigCtxt sel_name True - ; (sig_ty, hs_wrap) + = do { (sig_ty, hs_wrap) <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty ; let local_meth_ty = idType local_meth_id + ctxt = FunSigCtxt sel_name False + -- False <=> do not report redundant constraints when + -- checking instance-sig <= class-meth-sig + -- The instance-sig is the focus here; the class-meth-sig + -- is fixed (#18036) ; hs_wrap <- addErrCtxtM (methSigCtxt sel_name sig_ty local_meth_ty) $ tcSubType_NC ctxt sig_ty local_meth_ty ; return (sig_ty, hs_wrap) } ; inner_meth_name <- newName (nameOccName sel_name) - ; let inner_meth_id = mkLocalId inner_meth_name sig_ty + ; let ctxt = FunSigCtxt sel_name True + -- True <=> check for redundant constraints in the + -- user-specified instance signature + inner_meth_id = mkLocalId inner_meth_name sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt , sig_loc = getLoc (hsSigType hs_sig_ty) } ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -145,3 +145,7 @@ data Extension | CUSKs | StandaloneKindSignatures deriving (Eq, Enum, Show, Generic, Bounded) +-- 'Ord' and 'Bounded' are provided for GHC API users (see discussions +-- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and +-- https://gitlab.haskell.org/ghc/ghc/merge_requests/826). +instance Ord Extension where compare a b = compare (fromEnum a) (fromEnum b) ===================================== testsuite/tests/typecheck/should_compile/T18036.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +instance Fold Identity where + fold :: Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +-- Here we /should/ warn about redundant constraints in the +-- instance signature, since we can remove them +instance Fold Identity where + fold :: Monoid a => Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.stderr ===================================== @@ -0,0 +1,6 @@ + +T18036a.hs:14:13: warning: [-Wredundant-constraints] + • Redundant constraint: Monoid a + • In the type signature for: + fold :: forall a. Monoid a => Identity a -> a + In the instance declaration for ‘Fold Identity’ ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -703,3 +703,5 @@ test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) test('T18023', normal, compile, ['']) +test('T18036', normal, compile, ['']) +test('T18036a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b895317bff965a7f2aabc3bf83e118dff72b5fc0...72fbb1310056435e218e98c3f6875c93aa0a336d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b895317bff965a7f2aabc3bf83e118dff72b5fc0...72fbb1310056435e218e98c3f6875c93aa0a336d You're receiving 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 20 08:17:00 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 20 Apr 2020 04:17:00 -0400 Subject: [Git][ghc/ghc][wip/T17173] 4 commits: GHC.Core.Opt renaming Message-ID: <5e9d5a7cc4770_616713503ee058104a5@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 12ae4eda by Simon Peyton Jones at 2020-04-20T09:16:31+01:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 30 changed files: - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34287d9a676b83a50e15acecbe0be2e7232f1987...12ae4eda5ec2ac968a56cf97972bb75623536bce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34287d9a676b83a50e15acecbe0be2e7232f1987...12ae4eda5ec2ac968a56cf97972bb75623536bce You're receiving 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 20 08:17:35 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 20 Apr 2020 04:17:35 -0400 Subject: [Git][ghc/ghc][wip/T17917] 51 commits: Make NoExtCon fields strict Message-ID: <5e9d5a9f3fdb_6167136dfb9c58135e2@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - a6431f92 by Simon Peyton Jones at 2020-04-20T09:17:23+01:00 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. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6d9fd7cd87afa68586da31973fd49036aa566d39...a6431f92a2a5fbaf58a647d4b332c5c7222309f6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6d9fd7cd87afa68586da31973fd49036aa566d39...a6431f92a2a5fbaf58a647d4b332c5c7222309f6 You're receiving 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 20 08:36:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 20 Apr 2020 04:36:52 -0400 Subject: [Git][ghc/ghc][master] Derive Ord instance for Extension Message-ID: <5e9d5f2482931_61673f8198ee100c58204b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - 1 changed file: - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs Changes: ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -145,3 +145,7 @@ data Extension | CUSKs | StandaloneKindSignatures deriving (Eq, Enum, Show, Generic, Bounded) +-- 'Ord' and 'Bounded' are provided for GHC API users (see discussions +-- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and +-- https://gitlab.haskell.org/ghc/ghc/merge_requests/826). +instance Ord Extension where compare a b = compare (fromEnum a) (fromEnum b) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36882493fcaa9dd2eefa7184929765189ac339ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36882493fcaa9dd2eefa7184929765189ac339ad You're receiving 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 20 08:37:29 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 20 Apr 2020 04:37:29 -0400 Subject: [Git][ghc/ghc][master] Fix a buglet in redundant-constraint warnings Message-ID: <5e9d5f498c2d4_61673f8198ee100c5823541@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - 5 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/typecheck/should_compile/T18036.hs - + testsuite/tests/typecheck/should_compile/T18036a.hs - + testsuite/tests/typecheck/should_compile/T18036a.stderr - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1719,19 +1719,26 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind | Just hs_sig_ty <- hs_sig_fn sel_name -- There is a signature in the instance -- See Note [Instance method signatures] - = do { let ctxt = FunSigCtxt sel_name True - ; (sig_ty, hs_wrap) + = do { (sig_ty, hs_wrap) <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty ; let local_meth_ty = idType local_meth_id + ctxt = FunSigCtxt sel_name False + -- False <=> do not report redundant constraints when + -- checking instance-sig <= class-meth-sig + -- The instance-sig is the focus here; the class-meth-sig + -- is fixed (#18036) ; hs_wrap <- addErrCtxtM (methSigCtxt sel_name sig_ty local_meth_ty) $ tcSubType_NC ctxt sig_ty local_meth_ty ; return (sig_ty, hs_wrap) } ; inner_meth_name <- newName (nameOccName sel_name) - ; let inner_meth_id = mkLocalId inner_meth_name sig_ty + ; let ctxt = FunSigCtxt sel_name True + -- True <=> check for redundant constraints in the + -- user-specified instance signature + inner_meth_id = mkLocalId inner_meth_name sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt , sig_loc = getLoc (hsSigType hs_sig_ty) } ===================================== testsuite/tests/typecheck/should_compile/T18036.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +instance Fold Identity where + fold :: Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +-- Here we /should/ warn about redundant constraints in the +-- instance signature, since we can remove them +instance Fold Identity where + fold :: Monoid a => Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.stderr ===================================== @@ -0,0 +1,6 @@ + +T18036a.hs:14:13: warning: [-Wredundant-constraints] + • Redundant constraint: Monoid a + • In the type signature for: + fold :: forall a. Monoid a => Identity a -> a + In the instance declaration for ‘Fold Identity’ ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -703,3 +703,5 @@ test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) test('T18023', normal, compile, ['']) +test('T18036', normal, compile, ['']) +test('T18036a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b43365ad62d73afd5c58467ab9a4f9523ab09c18 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b43365ad62d73afd5c58467ab9a4f9523ab09c18 You're receiving 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 20 11:09:16 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 20 Apr 2020 07:09:16 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Derive Ord instance for Extension Message-ID: <5e9d82dca23d1_6167e4e49b458497c2@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - 1458e544 by Ömer Sinan Ağacan at 2020-04-20T07:09:11-04:00 Mark T12010 fragile on 32-bit - - - - - 9e0d18d7 by Ben Gamari at 2020-04-20T07:09:11-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 9 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - hadrian/ghci - hadrian/ghci-cabal - libraries/base/tests/IO/T12010/test.T - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/typecheck/should_compile/T18036.hs - + testsuite/tests/typecheck/should_compile/T18036a.hs - + testsuite/tests/typecheck/should_compile/T18036a.stderr - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1719,19 +1719,26 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind | Just hs_sig_ty <- hs_sig_fn sel_name -- There is a signature in the instance -- See Note [Instance method signatures] - = do { let ctxt = FunSigCtxt sel_name True - ; (sig_ty, hs_wrap) + = do { (sig_ty, hs_wrap) <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty ; let local_meth_ty = idType local_meth_id + ctxt = FunSigCtxt sel_name False + -- False <=> do not report redundant constraints when + -- checking instance-sig <= class-meth-sig + -- The instance-sig is the focus here; the class-meth-sig + -- is fixed (#18036) ; hs_wrap <- addErrCtxtM (methSigCtxt sel_name sig_ty local_meth_ty) $ tcSubType_NC ctxt sig_ty local_meth_ty ; return (sig_ty, hs_wrap) } ; inner_meth_name <- newName (nameOccName sel_name) - ; let inner_meth_id = mkLocalId inner_meth_name sig_ty + ; let ctxt = FunSigCtxt sel_name True + -- True <=> check for redundant constraints in the + -- user-specified instance signature + inner_meth_id = mkLocalId inner_meth_name sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt , sig_loc = getLoc (hsSigType hs_sig_ty) } ===================================== hadrian/ghci ===================================== @@ -1,4 +1,4 @@ #!/usr/bin/env bash # By default on Linux/MacOS we build Hadrian using Cabal -(. "hadrian/ghci-cabal" "$@") +(. "hadrian/ghci-cabal" $@) ===================================== hadrian/ghci-cabal ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" -ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci | tr '\n\r' ' ')" +ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m ===================================== libraries/base/tests/IO/T12010/test.T ===================================== @@ -1,7 +1,7 @@ test('T12010', - [ - extra_files(['cbits/']), - only_ways(['threaded1']), - extra_ways(['threaded1']), - cmd_prefix('WAY_FLAGS="' + ' '.join(config.way_flags['threaded1']) + '"')], + [extra_files(['cbits/']), + only_ways(['threaded1']), + extra_ways(['threaded1']), + when(wordsize(32), fragile(16572)), + cmd_prefix('WAY_FLAGS="' + ' '.join(config.way_flags['threaded1']) + '"')], makefile_test, []) ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -145,3 +145,7 @@ data Extension | CUSKs | StandaloneKindSignatures deriving (Eq, Enum, Show, Generic, Bounded) +-- 'Ord' and 'Bounded' are provided for GHC API users (see discussions +-- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and +-- https://gitlab.haskell.org/ghc/ghc/merge_requests/826). +instance Ord Extension where compare a b = compare (fromEnum a) (fromEnum b) ===================================== testsuite/tests/typecheck/should_compile/T18036.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +instance Fold Identity where + fold :: Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +-- Here we /should/ warn about redundant constraints in the +-- instance signature, since we can remove them +instance Fold Identity where + fold :: Monoid a => Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.stderr ===================================== @@ -0,0 +1,6 @@ + +T18036a.hs:14:13: warning: [-Wredundant-constraints] + • Redundant constraint: Monoid a + • In the type signature for: + fold :: forall a. Monoid a => Identity a -> a + In the instance declaration for ‘Fold Identity’ ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -703,3 +703,5 @@ test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) test('T18023', normal, compile, ['']) +test('T18036', normal, compile, ['']) +test('T18036a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/72fbb1310056435e218e98c3f6875c93aa0a336d...9e0d18d7484770a4609d84a4d68a30bb88783193 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/72fbb1310056435e218e98c3f6875c93aa0a336d...9e0d18d7484770a4609d84a4d68a30bb88783193 You're receiving 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 20 11:21:43 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 20 Apr 2020 07:21:43 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/alias_cmm_opt Message-ID: <5e9d85c7dd8af_6167e4e49b458564b4@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/alias_cmm_opt at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/alias_cmm_opt You're receiving 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 20 12:42:46 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 20 Apr 2020 08:42:46 -0400 Subject: [Git][ghc/ghc][wip/andreask/alias_cmm_opt] Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". Message-ID: <5e9d98c6ee273_616776d1c745869983@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/alias_cmm_opt at Glasgow Haskell Compiler / GHC Commits: eb916151 by Andreas Klebinger at 2020-04-20T14:42:36+02:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 2 changed files: - compiler/GHC/Driver/Session.hs - docs/users_guide/debugging.rst Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2661,6 +2661,8 @@ dynamic_flags_deps = [ (setDumpFlag Opt_D_dump_cmm_info) , make_ord_flag defGhcFlag "ddump-cmm-cps" (setDumpFlag Opt_D_dump_cmm_cps) + , make_ord_flag defGhcFlag "ddump-cmm-opt" + (setDumpFlag Opt_D_dump_opt_cmm) , make_ord_flag defGhcFlag "ddump-cfg-weights" (setDumpFlag Opt_D_dump_cfg_weights) , make_ord_flag defGhcFlag "ddump-core-stats" @@ -2769,7 +2771,7 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "ddump-rn-stats" (setDumpFlag Opt_D_dump_rn_stats) - , make_ord_flag defGhcFlag "ddump-opt-cmm" + , make_ord_flag defGhcFlag "ddump-opt-cmm" --old alias for cmm-opt (setDumpFlag Opt_D_dump_opt_cmm) , make_ord_flag defGhcFlag "ddump-simpl-stats" (setDumpFlag Opt_D_dump_simpl_stats) ===================================== docs/users_guide/debugging.rst ===================================== @@ -546,12 +546,18 @@ These flags dump various stages of the :ref:`native code generator's ` pipeline, which starts with C-\\- and produces native assembler. -.. ghc-flag:: -ddump-opt-cmm +.. ghc-flag:: -ddump-cmm-opt :shortdesc: Dump the results of C-\\- to C-\\- optimising passes :type: dynamic Dump the results of C-\\- to C-\\- optimising passes performed by the NCG. +.. ghc-flag:: -ddump-opt-cmm + :shortdesc: Dump the results of C-\\- to C-\\- optimising passes + :type: dynamic + + Alias for :ghc-flag:`-ddump-cmm-opt` + .. ghc-flag:: -ddump-asm-native :shortdesc: Dump initial assembly :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb916151ae1848e64b044123cc918da459c0cad9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb916151ae1848e64b044123cc918da459c0cad9 You're receiving 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 20 14:04:41 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Mon, 20 Apr 2020 10:04:41 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/buggymcbugfix/15185-enum-int Message-ID: <5e9dabf9930e_61673f8199536d94588445e@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed new branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/buggymcbugfix/15185-enum-int You're receiving 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 20 15:34:26 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 11:34:26 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/rip-out-fast-llvm Message-ID: <5e9dc1021aebb_616776d1c7459167a8@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/rip-out-fast-llvm at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/rip-out-fast-llvm You're receiving 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 20 16:40:26 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 20 Apr 2020 12:40:26 -0400 Subject: [Git][ghc/ghc][wip/T17775] 41 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5e9dd07a76eaa_616776d1c74593603d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 916e1fa8 by Simon Peyton Jones at 2020-04-18T22:58:25+01:00 Simplify subsumption This patch implements GHC Proposal 287: Simplify subsumption and ticket #17775. The highlights are: * No deeplyInstantiate or deeplySkolemise * No tcSubTypeDS Everything else is a knock-on effect. I did a bit of renaming to make things consistent * tcPolyExpr becomes tcCheckPolyExpr ditto tcPolyExprNC * Add new function tcCheckMonoExpr e ty = tcMon0Expr expr (mkCheckExpType ty) and use it This all comopiles, but needs some eta-expansion in haskeline, and doubtless other packages. - - - - - 94013d6c by Simon Peyton Jones at 2020-04-18T22:58:27+01:00 Further refactoring and simplification Reviewed the main changes with Richard I had to do eta-expansion in a number of tests: T10283 T10390 T14488 T1634 T4284 T9569a T9834 tc145 tc160 tc208 tc210 twins - - - - - a33a13f2 by Ben Gamari at 2020-04-18T22:58:27+01:00 Bump haskeline submodule - - - - - a4c47610 by Simon Peyton Jones at 2020-04-18T22:58:27+01:00 Delete commented-out code - - - - - c10e7aa6 by Simon Peyton Jones at 2020-04-18T22:58:27+01:00 Fix (breaking) typo - - - - - 381b0b47 by Simon Peyton Jones at 2020-04-18T22:58:27+01:00 Improve decomposition for FunTys This just improves error messages, avoiding Couldn't match type ‘Char’ with ‘Show a -> Char’ - - - - - 47c7c998 by Ryan Scott at 2020-04-18T22:58:28+01:00 Bump Cabal submodule As well as some miscellaneous fixes needed to make GHC itself compile under simplified subsumption. - - - - - 00e216d4 by Simon Peyton Jones at 2020-04-18T22:58:28+01:00 Wibbles * Get expected/actual the right way round * Relevant-bindings fixes - - - - - 600aa4a9 by Simon Peyton Jones at 2020-04-18T22:59:46+01:00 A lot more wibbles * Made String wired-in, so that "foo" :: String rather than "foo" :: [Char] * isTauTy: account for => * Bring dicts into scope when desugaring HsWrappers: addTyCsDs and hsWrapDictBinders * Improve reporting for occurs checks where skolems are involved e.g. 10715b, mc19, tcfail193, T13674, T4272, T3169, T7758, 7148 Payload is in the first case of mkTyVarEqErr * solveLocalEqualitesX: fail faster. we want to fail fast in T11142 Another example: T15629 And keep all equalities in dropMisleading. This gives better reporting in T12593 for example. * Move checkDataKindSig after the solveEqualities and zonk, obviously! * Move ic_telescope into ForAllSkol; a nice win. * Pretty-printing AbsBinds We are now very close to green - - - - - 272c664a by Ömer Sinan Ağacan at 2020-04-18T22:59:46+01:00 Revert accidental haddock change - - - - - bcf1b0ba by Simon Peyton Jones at 2020-04-18T22:59:48+01:00 More wibbles - - - - - f6438742 by Simon Peyton Jones at 2020-04-20T16:23:42+01:00 Wibbles - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Op/FloatIn.hs - compiler/GHC/Core/Op/OccurAnal.hs - compiler/GHC/Core/Op/SpecConstr.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Splice.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c64261abb387fc7a5accbb2e41c1ac61b80803c...f6438742bb8c3f6ebbf2bb9e9a8a0a7bd076fe9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c64261abb387fc7a5accbb2e41c1ac61b80803c...f6438742bb8c3f6ebbf2bb9e9a8a0a7bd076fe9a You're receiving 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 20 17:05:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 13:05:44 -0400 Subject: [Git][ghc/ghc][wip/fix-hadrian-ghci] 3 commits: Derive Ord instance for Extension Message-ID: <5e9dd668ae03d_6167f5265985949345@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/fix-hadrian-ghci at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - f6cb3236 by Ben Gamari at 2020-04-20T13:05:37-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 9 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - hadrian/ghci - hadrian/ghci-cabal - hadrian/ghci-stack - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - + testsuite/tests/typecheck/should_compile/T18036.hs - + testsuite/tests/typecheck/should_compile/T18036a.hs - + testsuite/tests/typecheck/should_compile/T18036a.stderr - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1719,19 +1719,26 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind | Just hs_sig_ty <- hs_sig_fn sel_name -- There is a signature in the instance -- See Note [Instance method signatures] - = do { let ctxt = FunSigCtxt sel_name True - ; (sig_ty, hs_wrap) + = do { (sig_ty, hs_wrap) <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty ; let local_meth_ty = idType local_meth_id + ctxt = FunSigCtxt sel_name False + -- False <=> do not report redundant constraints when + -- checking instance-sig <= class-meth-sig + -- The instance-sig is the focus here; the class-meth-sig + -- is fixed (#18036) ; hs_wrap <- addErrCtxtM (methSigCtxt sel_name sig_ty local_meth_ty) $ tcSubType_NC ctxt sig_ty local_meth_ty ; return (sig_ty, hs_wrap) } ; inner_meth_name <- newName (nameOccName sel_name) - ; let inner_meth_id = mkLocalId inner_meth_name sig_ty + ; let ctxt = FunSigCtxt sel_name True + -- True <=> check for redundant constraints in the + -- user-specified instance signature + inner_meth_id = mkLocalId inner_meth_name sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt , sig_loc = getLoc (hsSigType hs_sig_ty) } ===================================== hadrian/ghci ===================================== @@ -1,4 +1,4 @@ #!/usr/bin/env bash # By default on Linux/MacOS we build Hadrian using Cabal -(. "hadrian/ghci-cabal" "$@") +(. "hadrian/ghci-cabal" $@) ===================================== hadrian/ghci-cabal ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" -ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" +ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m ===================================== hadrian/ghci-stack ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -145,3 +145,7 @@ data Extension | CUSKs | StandaloneKindSignatures deriving (Eq, Enum, Show, Generic, Bounded) +-- 'Ord' and 'Bounded' are provided for GHC API users (see discussions +-- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and +-- https://gitlab.haskell.org/ghc/ghc/merge_requests/826). +instance Ord Extension where compare a b = compare (fromEnum a) (fromEnum b) ===================================== testsuite/tests/typecheck/should_compile/T18036.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +instance Fold Identity where + fold :: Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +-- Here we /should/ warn about redundant constraints in the +-- instance signature, since we can remove them +instance Fold Identity where + fold :: Monoid a => Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.stderr ===================================== @@ -0,0 +1,6 @@ + +T18036a.hs:14:13: warning: [-Wredundant-constraints] + • Redundant constraint: Monoid a + • In the type signature for: + fold :: forall a. Monoid a => Identity a -> a + In the instance declaration for ‘Fold Identity’ ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -703,3 +703,5 @@ test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) test('T18023', normal, compile, ['']) +test('T18036', normal, compile, ['']) +test('T18036a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7bfb54c815142556c027459241a07c40c964f225...f6cb3236612a2ebc0da7c61e2b528ab8da6ea630 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7bfb54c815142556c027459241a07c40c964f225...f6cb3236612a2ebc0da7c61e2b528ab8da6ea630 You're receiving 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 20 17:27:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 13:27:47 -0400 Subject: [Git][ghc/ghc][wip/rip-out-fast-llvm] llvmGen: Remove -fast-llvm flag Message-ID: <5e9ddb933df52_6167134ebbc459560be@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/rip-out-fast-llvm at Glasgow Haskell Compiler / GHC Commits: 0b57db5f by Ben Gamari at 2020-04-20T13:27:37-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 3 changed files: - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/expected-undocumented-flags.txt Changes: ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -866,20 +866,6 @@ getOutputFilename stop_phase output basename dflags next_phase maybe_location | otherwise = persistent --- | The fast LLVM Pipeline skips the mangler and assembler, --- emitting object code directly from llc. --- --- slow: opt -> llc -> .s -> mangler -> as -> .o --- fast: opt -> llc -> .o --- --- hidden flag: -ffast-llvm --- --- if keep-s-files is specified, we need to go through --- the slow pipeline (Kavon Farvardin requested this). -fastLlvmPipeline :: DynFlags -> Bool -fastLlvmPipeline dflags - = not (gopt Opt_KeepSFiles dflags) && gopt Opt_FastLlvm dflags - -- | LLVM Options. These are flags to be passed to opt and llc, to ensure -- consistency we list them in pairs, so that they form groups. llvmOptions :: DynFlags @@ -890,7 +876,6 @@ llvmOptions dflags = ,"-relocation-model=" ++ rmodel) | not (null rmodel)] ++ [("-stack-alignment=" ++ (show align) ,"-stack-alignment=" ++ (show align)) | align > 0 ] - ++ [("", "-filetype=obj") | fastLlvmPipeline dflags ] -- Additional llc flags ++ [("", "-mcpu=" ++ mcpu) | not (null mcpu) @@ -1472,8 +1457,7 @@ runPhase (RealPhase LlvmOpt) input_fn dflags runPhase (RealPhase LlvmLlc) input_fn dflags = do - next_phase <- if | fastLlvmPipeline dflags -> maybeMergeForeign - -- hidden debugging flag '-dno-llvm-mangler' to skip mangling + next_phase <- if -- hidden debugging flag '-dno-llvm-mangler' to skip mangling | gopt Opt_NoLlvmMangler dflags -> return (As False) | otherwise -> return LlvmMangle ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2815,8 +2815,6 @@ dynamic_flags_deps = [ (NoArg (setGeneralFlag Opt_D_faststring_stats)) , make_ord_flag defGhcFlag "dno-llvm-mangler" (NoArg (setGeneralFlag Opt_NoLlvmMangler)) -- hidden flag - , make_ord_flag defGhcFlag "fast-llvm" - (NoArg (setGeneralFlag Opt_FastLlvm)) -- hidden flag , make_ord_flag defGhcFlag "dno-typeable-binds" (NoArg (setGeneralFlag Opt_NoTypeableBinds)) , make_ord_flag defGhcFlag "ddump-debug" ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -78,7 +78,6 @@ -fallow-overlapping-instances -fallow-undecidable-instances -farrows --fast-llvm -fbang-patterns -fbuilding-cabal-package -fconstraint-solver-iterations View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b57db5f9a6ff27bb4a29464c3bfdaf5f3e7857b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b57db5f9a6ff27bb4a29464c3bfdaf5f3e7857b You're receiving 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 20 17:52:37 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 13:52:37 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/testsuite-fixes Message-ID: <5e9de165e1a9f_616776d1c74595655e@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/testsuite-fixes at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/testsuite-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 Mon Apr 20 17:53:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 13:53:17 -0400 Subject: [Git][ghc/ghc][wip/testsuite-fixes] 3 commits: Derive Ord instance for Extension Message-ID: <5e9de18d119c7_616776d1c74595677e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/testsuite-fixes at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - 262b2058 by Ben Gamari at 2020-04-20T13:53:09-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - 7 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - testsuite/driver/testlib.py - + testsuite/tests/typecheck/should_compile/T18036.hs - + testsuite/tests/typecheck/should_compile/T18036a.hs - + testsuite/tests/typecheck/should_compile/T18036a.stderr - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1719,19 +1719,26 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind | Just hs_sig_ty <- hs_sig_fn sel_name -- There is a signature in the instance -- See Note [Instance method signatures] - = do { let ctxt = FunSigCtxt sel_name True - ; (sig_ty, hs_wrap) + = do { (sig_ty, hs_wrap) <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty ; let local_meth_ty = idType local_meth_id + ctxt = FunSigCtxt sel_name False + -- False <=> do not report redundant constraints when + -- checking instance-sig <= class-meth-sig + -- The instance-sig is the focus here; the class-meth-sig + -- is fixed (#18036) ; hs_wrap <- addErrCtxtM (methSigCtxt sel_name sig_ty local_meth_ty) $ tcSubType_NC ctxt sig_ty local_meth_ty ; return (sig_ty, hs_wrap) } ; inner_meth_name <- newName (nameOccName sel_name) - ; let inner_meth_id = mkLocalId inner_meth_name sig_ty + ; let ctxt = FunSigCtxt sel_name True + -- True <=> check for redundant constraints in the + -- user-specified instance signature + inner_meth_id = mkLocalId inner_meth_name sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt , sig_loc = getLoc (hsSigType hs_sig_ty) } ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -145,3 +145,7 @@ data Extension | CUSKs | StandaloneKindSignatures deriving (Eq, Enum, Show, Generic, Bounded) +-- 'Ord' and 'Bounded' are provided for GHC API users (see discussions +-- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and +-- https://gitlab.haskell.org/ghc/ghc/merge_requests/826). +instance Ord Extension where compare a b = compare (fromEnum a) (fromEnum b) ===================================== testsuite/driver/testlib.py ===================================== @@ -1787,7 +1787,11 @@ def stdout_ok(name: TestName, way: WayName) -> bool: expected_stdout_file, actual_stdout_file) def read_stdout( name: TestName ) -> str: - return in_testdir(name, 'run.stdout').read_text(encoding='UTF-8') + path = in_testdir(name, 'run.stdout') + if path.exists(): + return path.read_text(encoding='UTF-8') + else: + return '' def dump_stdout( name: TestName ) -> None: s = read_stdout(name).strip() @@ -1805,7 +1809,11 @@ def stderr_ok(name: TestName, way: WayName) -> bool: whitespace_normaliser=normalise_whitespace) def read_stderr( name: TestName ) -> str: - return in_testdir(name, 'run.stderr').read_text(encoding='UTF-8') + path = in_testdir(name, 'run.stderr') + if path.exists(): + return path.read_text(encoding='UTF-8') + else: + return '' def dump_stderr( name: TestName ) -> None: s = read_stderr(name).strip() ===================================== testsuite/tests/typecheck/should_compile/T18036.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +instance Fold Identity where + fold :: Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE InstanceSigs #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} + +module T18036 where + +class Fold f where + fold :: Monoid m => f m -> m + +newtype Identity a = Identity a + +-- Here we /should/ warn about redundant constraints in the +-- instance signature, since we can remove them +instance Fold Identity where + fold :: Monoid a => Identity a -> a + fold (Identity a) = a ===================================== testsuite/tests/typecheck/should_compile/T18036a.stderr ===================================== @@ -0,0 +1,6 @@ + +T18036a.hs:14:13: warning: [-Wredundant-constraints] + • Redundant constraint: Monoid a + • In the type signature for: + fold :: forall a. Monoid a => Identity a -> a + In the instance declaration for ‘Fold Identity’ ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -703,3 +703,5 @@ test('T17024', normal, compile, ['']) test('T17021a', normal, compile, ['']) test('T18005', normal, compile, ['']) test('T18023', normal, compile, ['']) +test('T18036', normal, compile, ['']) +test('T18036a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ea35c2f67bab39426fd5621ac8230ec61f0faa1...262b205849ae03b73534f4195b0d41cef8a2ceb9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ea35c2f67bab39426fd5621ac8230ec61f0faa1...262b205849ae03b73534f4195b0d41cef8a2ceb9 You're receiving 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 20 18:19:44 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 20 Apr 2020 14:19:44 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 4 commits: Nested CPR Message-ID: <5e9de7c08a02c_6167136dfb9c596777f@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 5a397ca0 by Sebastian Graf at 2020-04-16T12:23:54+02:00 Nested CPR - - - - - fdccc292 by Sebastian Graf at 2020-04-16T13:10:28+02:00 Move tests from stranal to cpranal - - - - - 6c40caa7 by Sebastian Graf at 2020-04-16T13:13:19+02:00 Accept FacState - - - - - daa5dd02 by Sebastian Graf at 2020-04-20T20:18:57+02:00 Factor Cpr and Termination into a joint lattice As a result, we don't even have to export Termination from Cpr. Neat! Also I realised there is a simpler and more sound way to generate and unleash CPR signatures. - - - - - 30 changed files: - compiler/GHC/Core/Op/CprAnal.hs - compiler/GHC/Core/Op/WorkWrap.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/utils/Maybes.hs - testsuite/tests/stranal/sigs/CaseBinderCPR.hs → testsuite/tests/cpranal/sigs/CaseBinderCPR.hs - testsuite/tests/stranal/sigs/CaseBinderCPR.stderr → testsuite/tests/cpranal/sigs/CaseBinderCPR.stderr - testsuite/tests/stranal/sigs/FacState.hs → testsuite/tests/cpranal/sigs/FacState.hs - + testsuite/tests/cpranal/sigs/FacState.stderr - + testsuite/tests/cpranal/sigs/Makefile - testsuite/tests/stranal/should_compile/T10694.hs → testsuite/tests/cpranal/sigs/T10694.hs - + testsuite/tests/cpranal/sigs/T10694.stderr - testsuite/tests/stranal/sigs/T5075.hs → testsuite/tests/cpranal/sigs/T5075.hs - testsuite/tests/stranal/sigs/T5075.stderr → testsuite/tests/cpranal/sigs/T5075.stderr - + testsuite/tests/cpranal/sigs/all.T - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/lib/integer/Makefile - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9d6e30b7541f036e7237e34596431002c6a38fbc...daa5dd0204d1ccee6cfe780bd6fa1d7745b007fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9d6e30b7541f036e7237e34596431002c6a38fbc...daa5dd0204d1ccee6cfe780bd6fa1d7745b007fd You're receiving 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 20 18:39:36 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 20 Apr 2020 14:39:36 -0400 Subject: [Git][ghc/ghc][master] Mark T12010 fragile on 32-bit Message-ID: <5e9dec68ed8d9_6167865d29c5977699@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - 1 changed file: - libraries/base/tests/IO/T12010/test.T Changes: ===================================== libraries/base/tests/IO/T12010/test.T ===================================== @@ -1,7 +1,7 @@ test('T12010', - [ - extra_files(['cbits/']), - only_ways(['threaded1']), - extra_ways(['threaded1']), - cmd_prefix('WAY_FLAGS="' + ' '.join(config.way_flags['threaded1']) + '"')], + [extra_files(['cbits/']), + only_ways(['threaded1']), + extra_ways(['threaded1']), + when(wordsize(32), fragile(16572)), + cmd_prefix('WAY_FLAGS="' + ' '.join(config.way_flags['threaded1']) + '"')], makefile_test, []) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d5fae7da02cff1c7ec7b8e472f85d23aef098968 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d5fae7da02cff1c7ec7b8e472f85d23aef098968 You're receiving 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 20 20:45:35 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Mon, 20 Apr 2020 16:45:35 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 16 commits: Change the fail operator argument of BindStmt to be a Maybe Message-ID: <5e9e09ef61ecf_616713503ee06004243@gitlab.haskell.org.mail> John Ericson pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - c96ffe62 by John Ericson at 2020-04-20T16:45:07-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/35a4fdb9cb91a46df7d43778655383bd5e737574...c96ffe62fd1b3af4b7b13dfccf20f7b15aa1f7de -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/35a4fdb9cb91a46df7d43778655383bd5e737574...c96ffe62fd1b3af4b7b13dfccf20f7b15aa1f7de You're receiving 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 20 21:22:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 17:22:33 -0400 Subject: [Git][ghc/ghc][ghc-8.10] 9 commits: Force -fPIC for intree GMP (fix #17799) Message-ID: <5e9e12994f717_61673f81ef22dee46034655@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.10 at Glasgow Haskell Compiler / GHC Commits: 07c0d148 by Sylvain Henry at 2020-04-13T17:57:19-04:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). (cherry picked from commit e1e329448f3742b2024ca6bc2c78f36fe282b606) - - - - - 64fb49c9 by Ben Gamari at 2020-04-13T17:57:19-04:00 gitlab-ci: Add FreeBSD release job - - - - - d1464459 by Ben Gamari at 2020-04-13T17:57:19-04:00 Mention -Wunused-packages in release notes - - - - - 9ba0cd3e by Ben Gamari at 2020-04-13T17:57:19-04:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. (cherry picked from commit e5ee07ab565c1bf7a33d3bd4bcd3fb6c7b100d1c) - - - - - c0b4e2cc by Ben Gamari at 2020-04-13T17:57:19-04:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 2daee665 by Ben Gamari at 2020-04-13T17:57:19-04:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 12bb9912 by Ben Gamari at 2020-04-13T17:57:20-04:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 3717c610 by Ben Gamari at 2020-04-13T17:57:20-04:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 9ff90fd8 by Ben Gamari at 2020-04-13T17:57:20-04:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - 12 changed files: - .gitlab-ci.yml - compiler/main/DynFlags.hs - configure.ac - docs/users_guide/8.10.1-notes.rst - hadrian/src/Settings/Builders/Configure.hs - libraries/base/GHC/IO/FD.hs - libraries/integer-gmp/gmp/ghc.mk - libraries/integer-gmp/gmp/gmpsrc.patch - testsuite/tests/cmm/should_compile/Makefile - testsuite/tests/cmm/should_compile/T16930.stdout - testsuite/tests/driver/T16608/Makefile - testsuite/tests/runghc/all.T Changes: ===================================== .gitlab-ci.yml ===================================== @@ -344,6 +344,11 @@ nightly-x86_64-freebsd: extends: .build-x86_64-freebsd stage: full-build +release-x86_64-freebsd: + <<: *release + extends: .build-x86_64-freebsd + stage: full-build + .build-x86_64-freebsd-hadrian: extends: .validate-hadrian stage: full-build ===================================== compiler/main/DynFlags.hs ===================================== @@ -1817,7 +1817,9 @@ wayOptl :: Platform -> Way -> [String] wayOptl _ (WayCustom {}) = [] wayOptl platform WayThreaded = case platformOS platform of - OSFreeBSD -> ["-pthread"] + -- N.B. FreeBSD cc throws a warning if we pass -pthread without + -- actually using any pthread symbols. + OSFreeBSD -> ["-pthread", "-Wno-unused-command-line-argument"] OSOpenBSD -> ["-pthread"] OSNetBSD -> ["-pthread"] _ -> [] ===================================== configure.ac ===================================== @@ -836,7 +836,7 @@ AC_PATH_PROG(SPHINXBUILD,sphinx-build) AC_CACHE_CHECK([for version of sphinx-build], fp_cv_sphinx_version, changequote(, )dnl [if test -n "$SPHINXBUILD"; then - fp_cv_sphinx_version=`"$SPHINXBUILD" --version 2>&1 | sed 's/.* v\?\([0-9]\.[0-9]\.[0-9]\)/\1/' | head -n1`; + fp_cv_sphinx_version=`"$SPHINXBUILD" --version 2>&1 | sed 's/.* \([0-9]\.[0-9]\.[0-9]\)/\1/' | head -n1`; fi; changequote([, ])dnl ]) ===================================== docs/users_guide/8.10.1-notes.rst ===================================== @@ -187,6 +187,8 @@ Compiler has been removed. From this point forth GHC will only support floating point via SSE2. +- New :ghc-flag:`-Wunused-packages` warning reports unused packages. + - Add new flags :ghc-flag:`-Wunused-record-wildcards` and :ghc-flag:`-Wredundant-record-wildcards` which warn users when they have redundant or unused uses of a record wildcard match. ===================================== hadrian/src/Settings/Builders/Configure.hs ===================================== @@ -13,6 +13,7 @@ configureBuilderArgs = do hostPlatform <- getSetting HostPlatform buildPlatform <- getSetting BuildPlatform pure [ "--enable-shared=no" + , "--with-pic=yes" , "--host=" ++ hostPlatform , "--build=" ++ buildPlatform ] ===================================== libraries/base/GHC/IO/FD.hs ===================================== @@ -67,16 +67,13 @@ import System.Posix.Types c_DEBUG_DUMP :: Bool c_DEBUG_DUMP = False --- Darwin limits the length of writes to 2GB. See --- #17414. +-- Darwin limits the length of writes to 2GB. See #17414. +-- Moreover, Linux will only transfer up to 0x7ffff000 and interpreting the +-- result of write/read is tricky above 2GB due to its signed type. For +-- simplicity we therefore clamp on all platforms. clampWriteSize, clampReadSize :: Int -> Int -#if defined(darwin_HOST_OS) -clampWriteSize = min 0x7fffffff -clampReadSize = min 0x7fffffff -#else -clampWriteSize = id -clampReadSize = id -#endif +clampWriteSize = min 0x7ffff000 +clampReadSize = min 0x7ffff000 -- ----------------------------------------------------------------------------- -- The file-descriptor IO device ===================================== libraries/integer-gmp/gmp/ghc.mk ===================================== @@ -131,7 +131,7 @@ libraries/integer-gmp/gmp/libgmp.a libraries/integer-gmp/gmp/gmp.h: # run is the 'target' platform of the compiler we're building. cd libraries/integer-gmp/gmp/gmpbuild; \ CC=$(CCX) CXX=$(CCX) NM=$(NM) AR=$(AR_STAGE1) ./configure \ - --enable-shared=no \ + --enable-shared=no --with-pic=yes \ --host=$(TARGETPLATFORM) --build=$(BUILDPLATFORM) $(MAKE) -C libraries/integer-gmp/gmp/gmpbuild MAKEFLAGS= $(CP) libraries/integer-gmp/gmp/gmpbuild/gmp.h libraries/integer-gmp/gmp/ ===================================== libraries/integer-gmp/gmp/gmpsrc.patch ===================================== @@ -1,27 +1,6 @@ diff -Naur gmp-6.1.2/configure gmpbuild/configure --- gmp-6.1.2/configure 2016-12-16 10:45:32.000000000 -0500 +++ gmpbuild/configure 2017-01-29 15:18:01.037775639 -0500 -@@ -4087,8 +4087,8 @@ - # - cclist="gcc cc" - --gcc_cflags="-O2 -pedantic" --gcc_64_cflags="-O2 -pedantic" -+gcc_cflags="-O2 -pedantic -fPIC" -+gcc_64_cflags="-O2 -pedantic -fPIC" - cc_cflags="-O" - cc_64_cflags="-O" - -@@ -27273,6 +27273,9 @@ - case $host in - *-*-darwin*) - -+echo "define(,)" >> $gmp_tmpconfigm4 -+ -+ - echo "include_mpn(\`x86_64/darwin.m4')" >> $gmp_tmpconfigm4i - ;; - *-*-mingw* | *-*-cygwin) @@ -28181,7 +28181,7 @@ # FIXME: Upcoming version of autoconf/automake may not like broken lines. # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. @@ -63,27 +42,3 @@ diff -Naur gmp-6.1.2/Makefile.in gmpbuild/Makefile.in # The "test -f" support for srcdir!=builddir is similar to the automake .c.o # etc rules, but with each foo.c explicitly, since $< is not portable -diff -Naur gmp-6.1.2/configure.ac gmpbuild/configure.ac ---- gmp-6.1.2/configure.ac 2016-12-16 10:45:27.000000000 -0500 -+++ gmpbuild/configure.ac 2017-01-29 22:47:28.469558006 -0500 -@@ -3698,7 +3698,8 @@ - AC_DEFINE(HAVE_HOST_CPU_FAMILY_x86_64) - case $host in - *-*-darwin*) -+ GMP_DEFINE_RAW(["define(,)"]) - GMP_INCLUDE_MPN(x86_64/darwin.m4) ;; - *-*-mingw* | *-*-cygwin) - GMP_INCLUDE_MPN(x86_64/dos64.m4) ;; - *-openbsd*) -diff -Naur gmp-6.1.2/mpn/asm-defs.m4 gmpbuild/mpn/asm-defs.m4 ---- gmp-6.1.2/mpn/asm-defs.m4 2016-12-16 10:45:27.000000000 -0500 -+++ gmpbuild/mpn/asm-defs.m4 2017-01-29 22:46:26.025176258 -0500 -@@ -1051,7 +1051,7 @@ - dnl systems which are always PIC. PIC_ALWAYS established in config.m4 - dnl identifies these for us. - --ifelse(`PIC_ALWAYS',`yes',`define(`PIC')') -+ifelse(PIC_ALWAYS,yes,`define(`PIC')') - - - dnl Various possible defines passed from the Makefile that are to be tested ===================================== testsuite/tests/cmm/should_compile/Makefile ===================================== @@ -7,9 +7,9 @@ include $(TOP)/mk/test.mk T16930: echo "testing -ddump-cmm-verbose for T16930 ..." '$(TEST_HC)' $(TEST_HC_OPTS) T16930.hs -fforce-recomp -ddump-cmm-verbose -ddump-to-file - grep -rl "CAFEnv" . --include=\T16930.* - grep -rl "Post control-flow optimisations" . --include=\T16930.* - grep -rl "Post CPS Cmm" . --include=\T16930.* - grep -rl "after setInfoTableStackMap" . --include=\T16930.* - grep -rl "Layout Stack" . --include=\T16930.* - grep -rl "Post switch plan" . --include=\T16930.* + grep -rl "CAFEnv" `ls T16930.*` + grep -rl "Post control-flow optimisations" `ls T16930.*` + grep -rl "Post CPS Cmm" `ls T16930.*` + grep -rl "after setInfoTableStackMap" `ls T16930.*` + grep -rl "Layout Stack" `ls T16930.*` + grep -rl "Post switch plan" `ls T16930.*` ===================================== testsuite/tests/cmm/should_compile/T16930.stdout ===================================== @@ -1,9 +1,9 @@ testing -ddump-cmm-verbose for T16930 ... [1 of 1] Compiling Main ( T16930.hs, T16930.o ) Linking T16930 ... -./T16930.dump-cmm-caf -./T16930.dump-cmm-cfg -./T16930.dump-cmm-cps -./T16930.dump-cmm-info -./T16930.dump-cmm-sp -./T16930.dump-cmm-switch +T16930.dump-cmm-caf +T16930.dump-cmm-cfg +T16930.dump-cmm-cps +T16930.dump-cmm-info +T16930.dump-cmm-sp +T16930.dump-cmm-switch ===================================== testsuite/tests/driver/T16608/Makefile ===================================== @@ -3,6 +3,8 @@ include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk T16608_1: + # FreeBSD's sed doesn't like operating in-place on symlinks. Un-symlinkify. + mv MyInteger.hs tmp.hs; cp tmp.hs MyInteger.hs '$(TEST_HC)' $(TEST_HC_OPTS) --make -O0 T16608_1.hs ./T16608_1 sleep 1 @@ -11,6 +13,8 @@ T16608_1: ./T16608_1 T16608_2: + # FreeBSD's sed doesn't like operating in-place on symlinks. Un-symlinkify. + mv MyInteger.hs tmp.hs; cp tmp.hs MyInteger.hs '$(TEST_HC)' $(TEST_HC_OPTS) --make -O0 T16608_2.hs ./T16608_2 sleep 1 ===================================== testsuite/tests/runghc/all.T ===================================== @@ -4,7 +4,9 @@ test('T8601', req_interp, makefile_test, []) test('T11247', [req_interp, expect_broken(11247)], makefile_test, []) -test('T6132', [when(opsys('darwin'), expect_broken(6132))], compile, ['']) +test('T6132', [ + when(opsys('darwin') or opsys('freebsd'), expect_broken(6132))], + compile, ['']) test('T17171a', [req_interp, expect_fail], makefile_test, []) test('T17171b', req_interp, makefile_test, []) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c3cadf5db0d7eb859ff2c278ab07585c7df17b5...9ff90fd85e2c611a97ba36357ec50972d32db850 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c3cadf5db0d7eb859ff2c278ab07585c7df17b5...9ff90fd85e2c611a97ba36357ec50972d32db850 You're receiving 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 20 21:22:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 17:22:36 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/backports Message-ID: <5e9e129cd5dc6_6167e4e49b460348f6@gitlab.haskell.org.mail> Ben Gamari deleted branch wip/backports 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 20 22:01:05 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Mon, 20 Apr 2020 18:01:05 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5e9e1ba124143_61673f81ef22dee4604399c@gitlab.haskell.org.mail> John Ericson pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: e0df84fd by John Ericson at 2020-04-20T18:00:34-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -358,6 +358,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -10,6 +10,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] @@ -23,8 +24,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +63,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import GHC.Builtin.Types import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +74,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +174,12 @@ data Pat p -- For details on above see note [Api annotations] in GHC.Parser.Annotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +245,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +278,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +305,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +327,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +527,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +563,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +578,37 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +647,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +732,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +748,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +765,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +786,14 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +835,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +861,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +873,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +902,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -89,6 +92,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -135,6 +139,7 @@ import GHC.Settings.Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -197,8 +202,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -231,7 +239,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -436,25 +444,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -801,11 +826,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -880,8 +905,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -890,6 +917,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -979,49 +1007,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1045,19 +1093,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _) = collectPatBinders pat @@ -1072,47 +1124,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1394,10 +1464,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -267,7 +267,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -313,7 +313,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -512,8 +512,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -522,9 +522,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1117,8 +1120,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1135,7 +1139,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -143,9 +143,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; match_result <- match (group_arg_vars ++ vars) ty eqns' ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -171,10 +178,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -723,14 +723,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -760,7 +760,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,15 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon e + GhcRn -> noExtCon e +#endif + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -603,7 +603,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1077,7 +1077,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1114,7 +1118,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2065,7 +2073,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1823,13 +1824,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -503,7 +503,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -794,12 +794,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -828,13 +831,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -879,13 +886,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -941,7 +941,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -974,8 +974,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1125,10 +1123,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1295,7 +1297,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1357,13 +1359,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1383,12 +1388,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1419,19 +1431,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1450,7 +1463,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 20bf93490b37c0410d85a0ad4d38f9ddc2253589 +Subproject commit da4e2bd788b6231494d6ac56a8e88bcfa4be51f6 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0df84fd2e842bc096ddd8bb858c32535af67c5a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0df84fd2e842bc096ddd8bb858c32535af67c5a You're receiving 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 20 23:12:33 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 20 Apr 2020 19:12:33 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5e9e2c61170ff_6167e4e49b460653bb@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: 942dd105 by Andreas Klebinger at 2020-04-21T01:10:53+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 15 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs - compiler/GHC/CmmToAsm/Reg/Linear/State.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86.hs - compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/utils/Outputable.hs - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -729,7 +729,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count let optimizedCFG :: Maybe CFG optimizedCFG = - optimizeCFG (cfgWeightInfo dflags) cmm <$!> postShortCFG + optimizeCFG (gopt Opt_CmmStaticPred dflags) (cfgWeightInfo dflags) cmm <$!> postShortCFG maybeDumpCfg dflags optimizedCFG "CFG Weights - Final" proc_name ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -639,17 +639,19 @@ sequenceChain _info _weights [x] = [x] sequenceChain info weights' blocks@((BasicBlock entry _):_) = let weights :: CFG weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' + -- cfg' + weights' where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights + -- TODO: Remove + -- (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' + -- cfg' = {-# SCC rewriteEdges #-} + -- mapFoldlWithKey + -- (\cfg from m -> + -- mapFoldlWithKey + -- (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + -- cfg m ) + -- weights' + -- globalEdgeWeights directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,21 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - -optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG -optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG :: Bool -> D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optimizeCFG _ _ (CmmData {}) cfg = cfg +optimizeCFG doStaticPred weights proc@(CmmProc _info _lab _live graph) cfg = + (if doStaticPred then staticPredCfg (g_entry graph) else id) $ + optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +759,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +947,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,12 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +252,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +287,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +331,21 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + + -- assig <- getBlockAssigR + -- pprTraceM "assignment" $ ppr assig + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +381,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +408,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are love on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> BlockId -- ^ the id of the current block, for debugging @@ -476,7 +488,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +498,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,10 +538,12 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. - -- when (not $ null fixup_blocks) $ - -- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) +-- when (not $ null fixup_blocks) $ +-- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) -- (e) Delete all register assignments for temps which are read -- (only) and die here. Update the free register list. @@ -737,7 +752,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +764,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +795,19 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a (potential empty) list of preferred real registers. +findPrefRealReg :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe RealReg) +findPrefRealReg vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe RealReg -> Maybe RealReg + findVirtRegAssig assig z = + z <|> case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> Just real_reg + Just (InBoth real_reg _) -> Just real_reg + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,18 +824,26 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + -- Can we put the variable into a register it already was? + pref_reg <- findPrefRealReg r + case freeRegs_thisClass of -- case (2): we have a free register - (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + (first_free : _) -> + do let final_reg + | Just reg <- pref_reg + , reg `elem` freeRegs_thisClass + = reg + | otherwise + = first_free + spills' <- loadTemp r spill_loc final_reg spills - setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) - setFreeRegsR $ frAllocateReg platform my_reg freeRegs + setAssigR (addToUFM assig r $! newLocation spill_loc final_reg) + setFreeRegsR $ frAllocateReg platform final_reg freeRegs - allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs + allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs -- case (3): we need to push something out to free up a register @@ -814,7 +851,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,8 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -181,6 +181,7 @@ data GeneralFlag | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink + | Opt_CmmStaticPred | Opt_CmmElimCommonBlocks | Opt_AsmShortcutting | Opt_OmitYields ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3523,6 +3523,7 @@ fFlagsDeps = [ flagSpec "case-folding" Opt_CaseFolding, flagSpec "cmm-elim-common-blocks" Opt_CmmElimCommonBlocks, flagSpec "cmm-sink" Opt_CmmSink, + flagSpec "cmm-static-pred" Opt_CmmStaticPred, flagSpec "cse" Opt_CSE, flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, @@ -4074,6 +4075,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CmmElimCommonBlocks) , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) + , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) , ([1,2], Opt_StgCSE) , ([2], Opt_StgLiftLams) ===================================== compiler/utils/Outputable.hs ===================================== @@ -847,6 +847,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -214,6 +214,19 @@ by saying ``-fno-wombat``. to their usage sites. It also inlines simple expressions like literals or registers. +.. ghc-flag:: -fcmm-static-pred + :shortdesc: Enable static control flow prediction :ghc-flag:`-O`. + :type: dynamic + :reverse: -fno-cmm-static-pred + :category: + + :default: off but enabled with :ghc-flag:`-O`. + + This enables static control flow prediction on the final Cmm + code. If enabled GHC will apply certain heuristics to identify + loops and hot code paths. This information is then used by the + register allocation and code layout passes. + .. ghc-flag:: -fasm-shortcutting :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/942dd105476c15f4be50840a795b6b80668113c3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/942dd105476c15f4be50840a795b6b80668113c3 You're receiving 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 20 23:15:24 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 20 Apr 2020 19:15:24 -0400 Subject: [Git][ghc/ghc][wip/andreask/alias_cmm_opt] 42 commits: testsuite: Fix comment for a language extension Message-ID: <5e9e2d0ce477_6167f52659860674d8@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/alias_cmm_opt at Glasgow Haskell Compiler / GHC Commits: 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - c81264bf by Andreas Klebinger at 2020-04-20T19:15:18-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Class.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb916151ae1848e64b044123cc918da459c0cad9...c81264bf9102edff12d0db83698c12ecb6a18f4d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb916151ae1848e64b044123cc918da459c0cad9...c81264bf9102edff12d0db83698c12ecb6a18f4d You're receiving 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 20 23:18:14 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 20 Apr 2020 19:18:14 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Mark T12010 fragile on 32-bit Message-ID: <5e9e2db68458_6167134ebbc460708a@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - fecc28e0 by Adam Sandberg Ericsson at 2020-04-20T19:17:41-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - a49f5637 by Sylvain Henry at 2020-04-20T19:17:48-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - bbd8ec6d by Sylvain Henry at 2020-04-20T19:17:48-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - f9ae6b07 by Sylvain Henry at 2020-04-20T19:17:48-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - 393140fb by Sylvain Henry at 2020-04-20T19:17:48-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - 639dcb44 by Sylvain Henry at 2020-04-20T19:17:48-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - e9882a92 by Sylvain Henry at 2020-04-20T19:17:48-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - 8f1bffe5 by Alexis King at 2020-04-20T19:17:55-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 38fd3231 by Simon Peyton Jones at 2020-04-20T19:17:57-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 3d402d55 by Sylvain Henry at 2020-04-20T19:17:59-04:00 MachO linker: display section name - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9e0d18d7484770a4609d84a4d68a30bb88783193...3d402d556bd0e1d046d38cd4f33c73271fae3be0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9e0d18d7484770a4609d84a4d68a30bb88783193...3d402d556bd0e1d046d38cd4f33c73271fae3be0 You're receiving 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 21 00:32:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 20 Apr 2020 20:32:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/noinline-panic Message-ID: <5e9e3f2feb6c1_616713503ee060823ec@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/noinline-panic at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/noinline-panic You're receiving 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 21 03:44:32 2020 From: gitlab at gitlab.haskell.org (Moritz Angermann) Date: Mon, 20 Apr 2020 23:44:32 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/angerman/fix-macos-linker Message-ID: <5e9e6c20c24ef_616765c7a28608746f@gitlab.haskell.org.mail> Moritz Angermann pushed new branch wip/angerman/fix-macos-linker at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/angerman/fix-macos-linker You're receiving 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 21 04:48:44 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 21 Apr 2020 00:48:44 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: docs: drop note about not supporting shared libraries on unix systems Message-ID: <5e9e7b2c54a33_61673f81ef22dee4609908@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 1e55dabf by Adam Sandberg Ericsson at 2020-04-21T00:48:21-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - c01b636f by Sylvain Henry at 2020-04-21T00:48:23-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 1abbb1a2 by Sylvain Henry at 2020-04-21T00:48:23-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 2c46a988 by Sylvain Henry at 2020-04-21T00:48:23-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - f6c78675 by Sylvain Henry at 2020-04-21T00:48:23-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - 15723a0d by Sylvain Henry at 2020-04-21T00:48:23-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 8062f7d5 by Sylvain Henry at 2020-04-21T00:48:23-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - 8a6ca45a by Alexis King at 2020-04-21T00:48:24-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 0e39d214 by Simon Peyton Jones at 2020-04-21T00:48:26-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 0e2805c9 by Andreas Klebinger at 2020-04-21T00:48:27-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - c4dc2796 by Sylvain Henry at 2020-04-21T00:48:29-04:00 MachO linker: display section name - - - - - 226a9732 by Ben Gamari at 2020-04-21T00:48:30-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d402d556bd0e1d046d38cd4f33c73271fae3be0...226a97320f1a34173b96f6658b137c3a528ebd55 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d402d556bd0e1d046d38cd4f33c73271fae3be0...226a97320f1a34173b96f6658b137c3a528ebd55 You're receiving 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 21 09:35:03 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 21 Apr 2020 05:35:03 -0400 Subject: [Git][ghc/ghc][wip/andreask/tune_layout] NCG: Codelayout: Distinguish conditional and other branches. Message-ID: <5e9ebe474588c_6167f526598614307a@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/tune_layout at Glasgow Haskell Compiler / GHC Commits: fbf471f0 by Andreas Klebinger at 2020-04-21T11:34:45+02:00 NCG: Codelayout: Distinguish conditional and other branches. In #18053 we ended up with a suboptimal code layout because the code layout algorithm didn't distinguish between conditional and unconditional control flow. We can completely eliminate unconditional control flow instructions by placing blocks next to each other, not so much for conditionals. In terms of implementation we simply give conditional branches less weight before computing the layout. Fixes #18053 - - - - - 1 changed file: - compiler/GHC/CmmToAsm/BlockLayout.hs Changes: ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -240,7 +240,44 @@ import Control.Monad (foldM) Assuming that Lwork is large the chance that the "call" ends up in the same cache line is also fairly small. --} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~ Note [Layout relevant edge weights] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The input to the chain based code layout algorithm is a CFG + with edges annotated with their frequency. The frequency + of traversal corresponds quite well to the cost of not placing + the connected blocks next to each other. + + However even if having the same frequency certain edges are + inherently more or less relevant to code layout. + + In particular: + + * Edges which cross an info table are less relevant than others. + + If we place the blocks across this edge next to each other + they are still separated by the info table which negates + much of the benefit. It makes it less likely both blocks + will share a cache line reducing the benefits from locality. + But it also prevents us from eliminating jump instructions. + + * Conditional branches and switches are slightly less relevant. + + We can completely remove unconditional jumps by placing them + next to each other. This is not true for conditional branch edges. + We apply a small modifier to them to ensure edges for which we can + eliminate the overhead completely are considered first. See also #18053. + + * Edges constituted by a call are ignored. + + Considering these hardly helped with performance and ignoring + them helps quite a bit to improve compiler performance. + + So we perform a preprocessing step where we apply a multiplicator + to these kinds of edges. + + -} -- | Look at X number of blocks in two chains to determine @@ -654,17 +691,31 @@ sequenceChain info weights' blocks@((BasicBlock entry _):_) = directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where + -- Apply modifiers to turn edge frequencies into useable weights + -- for computing code layout. + -- See also Note [Layout relevant edge weights] relevantWeight :: CfgEdge -> Maybe CfgEdge relevantWeight edge@(CfgEdge from to edgeInfo) | (EdgeInfo CmmSource { trans_cmmNode = CmmCall {} } _) <- edgeInfo - -- Ignore edges across calls + -- Ignore edges across calls. = Nothing | mapMember to info , w <- edgeWeight edgeInfo - -- The payoff is small if we jump over an info table + -- The payoff is quite small if we jump over an info table = Just (CfgEdge from to edgeInfo { edgeWeight = w/8 }) + | (EdgeInfo CmmSource { trans_cmmNode = exitNode } _) <- edgeInfo + , cantEliminate exitNode + , w <- edgeWeight edgeInfo + -- A small penalty to edge types which + -- we can't optimize away by layout. + -- w * 0.96875 == w - w/32 + = Just (CfgEdge from to edgeInfo { edgeWeight = w * 0.96875 }) | otherwise = Just edge + where + cantEliminate CmmCondBranch {} = True + cantEliminate CmmSwitch {} = True + cantEliminate _ = False blockMap :: LabelMap (GenBasicBlock i) blockMap View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbf471f0405600776b0f6a91aa31b5e2a902194c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbf471f0405600776b0f6a91aa31b5e2a902194c You're receiving 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 21 10:38:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 21 Apr 2020 06:38:50 -0400 Subject: [Git][ghc/ghc][master] docs: drop note about not supporting shared libraries on unix systems Message-ID: <5e9ecd3a28764_616713503ee061501c2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 1 changed file: - docs/users_guide/packages.rst Changes: ===================================== docs/users_guide/packages.rst ===================================== @@ -1339,8 +1339,6 @@ The allowed fields, with their types, are: ``libHSfoo.a`` The name of the library on Unix and Windows (mingw) systems. - Note that we don't support building dynamic libraries of Haskell - code on Unix systems. ``HSfoo.dll`` The name of the dynamic library on Windows systems (optional). View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bca02fca0119354a6201fd5d019a553015ba2dd8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bca02fca0119354a6201fd5d019a553015ba2dd8 You're receiving 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 21 10:39:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 21 Apr 2020 06:39:54 -0400 Subject: [Git][ghc/ghc][master] 6 commits: Use ParserFlags in GHC.Runtime.Eval (#17957) Message-ID: <5e9ecd7a4424b_6167f526598615559a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - 28 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Types.hs - compiler/main/ErrUtils.hs - compiler/utils/Outputable.hs - ghc/GHCi/UI.hs - libraries/ghc-boot/GHC/Platform.hs - testsuite/tests/ghc-api/T9015.hs - testsuite/tests/regalloc/regalloc_unit_tests.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE LambdaCase #-} module GHC.Cmm.CLabel ( CLabel, -- abstract type @@ -131,6 +132,7 @@ import GHC.Platform import GHC.Types.Unique.Set import Util import GHC.Core.Ppr ( {- instances -} ) +import GHC.CmmToAsm.Config -- ----------------------------------------------------------------------------- -- The CLabel type @@ -1026,23 +1028,21 @@ isLocalCLabel this_mod lbl = -- that data resides in a DLL or not. [Win32 only.] -- @labelDynamic@ returns @True@ if the label is located -- in a DLL, be it a data reference or not. -labelDynamic :: DynFlags -> Module -> CLabel -> Bool -labelDynamic dflags this_mod lbl = +labelDynamic :: NCGConfig -> Module -> CLabel -> Bool +labelDynamic config this_mod lbl = case lbl of -- is the RTS in a DLL or not? RtsLabel _ -> externalDynamicRefs && (this_pkg /= rtsUnitId) IdLabel n _ _ -> - isDynLinkName dflags this_mod n + externalDynamicRefs && isDynLinkName platform this_mod n -- When compiling in the "dyn" way, each package is to be linked into -- its own shared library. CmmLabel pkg _ _ - | os == OSMinGW32 -> - externalDynamicRefs && (this_pkg /= pkg) - | otherwise -> - gopt Opt_ExternalDynamicRefs dflags + | os == OSMinGW32 -> externalDynamicRefs && (this_pkg /= pkg) + | otherwise -> externalDynamicRefs LocalBlockLabel _ -> False @@ -1079,8 +1079,9 @@ labelDynamic dflags this_mod lbl = -- Note that DynamicLinkerLabels do NOT require dynamic linking themselves. _ -> False where - externalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags - os = platformOS (targetPlatform dflags) + externalDynamicRefs = ncgExternalDynamicRefs config + platform = ncgPlatform config + os = platformOS platform this_pkg = moduleUnitId this_mod @@ -1168,93 +1169,85 @@ instance Outputable CLabel where ppr c = sdocWithDynFlags $ \dynFlags -> pprCLabel dynFlags c pprCLabel :: DynFlags -> CLabel -> SDoc +pprCLabel dflags = \case + (LocalBlockLabel u) -> tempLabelPrefixOrUnderscore <> pprUniqueAlways u + + (AsmTempLabel u) + | not (platformUnregisterised platform) + -> tempLabelPrefixOrUnderscore <> pprUniqueAlways u + + (AsmTempDerivedLabel l suf) + | useNCG + -> ptext (asmTempLabelPrefix platform) + <> case l of AsmTempLabel u -> pprUniqueAlways u + LocalBlockLabel u -> pprUniqueAlways u + _other -> pprCLabel dflags l + <> ftext suf + + (DynamicLinkerLabel info lbl) + | useNCG + -> pprDynamicLinkerAsmLabel platform info lbl + + PicBaseLabel + | useNCG + -> text "1b" + + (DeadStripPreventer lbl) + | useNCG + -> + {- + `lbl` can be temp one but we need to ensure that dsp label will stay + in the final binary so we prepend non-temp prefix ("dsp_") and + optional `_` (underscore) because this is how you mark non-temp symbols + on some platforms (Darwin) + -} + maybe_underscore $ text "dsp_" <> pprCLabel dflags lbl <> text "_dsp" + + (StringLitLabel u) + | useNCG + -> pprUniqueAlways u <> ptext (sLit "_str") + + lbl -> getPprStyle $ \sty -> + if useNCG && asmStyle sty + then maybe_underscore $ pprAsmCLbl lbl + else pprCLbl dflags lbl -pprCLabel _ (LocalBlockLabel u) - = tempLabelPrefixOrUnderscore <> pprUniqueAlways u - -pprCLabel dynFlags (AsmTempLabel u) - | not (platformUnregisterised $ targetPlatform dynFlags) - = tempLabelPrefixOrUnderscore <> pprUniqueAlways u - -pprCLabel dynFlags (AsmTempDerivedLabel l suf) - | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags - = ptext (asmTempLabelPrefix $ targetPlatform dynFlags) - <> case l of AsmTempLabel u -> pprUniqueAlways u - LocalBlockLabel u -> pprUniqueAlways u - _other -> pprCLabel dynFlags l - <> ftext suf - -pprCLabel dynFlags (DynamicLinkerLabel info lbl) - | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags - = pprDynamicLinkerAsmLabel (targetPlatform dynFlags) info lbl - -pprCLabel dynFlags PicBaseLabel - | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags - = text "1b" - -pprCLabel dynFlags (DeadStripPreventer lbl) - | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags - = - {- - `lbl` can be temp one but we need to ensure that dsp label will stay - in the final binary so we prepend non-temp prefix ("dsp_") and - optional `_` (underscore) because this is how you mark non-temp symbols - on some platforms (Darwin) - -} - maybe_underscore dynFlags $ text "dsp_" - <> pprCLabel dynFlags lbl <> text "_dsp" - -pprCLabel dynFlags (StringLitLabel u) - | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags - = pprUniqueAlways u <> ptext (sLit "_str") - -pprCLabel dynFlags lbl - = getPprStyle $ \ sty -> - if platformMisc_ghcWithNativeCodeGen (platformMisc dynFlags) && asmStyle sty - then maybe_underscore dynFlags $ pprAsmCLbl (targetPlatform dynFlags) lbl - else pprCLbl lbl - -maybe_underscore :: DynFlags -> SDoc -> SDoc -maybe_underscore dynFlags doc = - if platformMisc_leadingUnderscore $ platformMisc dynFlags - then pp_cSEP <> doc - else doc - -pprAsmCLbl :: Platform -> CLabel -> SDoc -pprAsmCLbl platform (ForeignLabel fs (Just sz) _ _) - | platformOS platform == OSMinGW32 - -- In asm mode, we need to put the suffix on a stdcall ForeignLabel. - -- (The C compiler does this itself). - = ftext fs <> char '@' <> int sz -pprAsmCLbl _ lbl - = pprCLbl lbl - -pprCLbl :: CLabel -> SDoc -pprCLbl (StringLitLabel u) - = pprUniqueAlways u <> text "_str" - -pprCLbl (SRTLabel u) - = tempLabelPrefixOrUnderscore <> pprUniqueAlways u <> pp_cSEP <> text "srt" - -pprCLbl (LargeBitmapLabel u) = - tempLabelPrefixOrUnderscore - <> char 'b' <> pprUniqueAlways u <> pp_cSEP <> text "btm" --- Some bitsmaps for tuple constructors have a numeric tag (e.g. '7') --- until that gets resolved we'll just force them to start --- with a letter so the label will be legal assembly code. - - -pprCLbl (CmmLabel _ str CmmCode) = ftext str -pprCLbl (CmmLabel _ str CmmData) = ftext str -pprCLbl (CmmLabel _ str CmmPrimCall) = ftext str - -pprCLbl (LocalBlockLabel u) = - tempLabelPrefixOrUnderscore <> text "blk_" <> pprUniqueAlways u - -pprCLbl (RtsLabel (RtsApFast str)) = ftext str <> text "_fast" - -pprCLbl (RtsLabel (RtsSelectorInfoTable upd_reqd offset)) - = sdocWithDynFlags $ \dflags -> + where + platform = targetPlatform dflags + useNCG = platformMisc_ghcWithNativeCodeGen (platformMisc dflags) + + maybe_underscore :: SDoc -> SDoc + maybe_underscore doc = + if platformMisc_leadingUnderscore $ platformMisc dflags + then pp_cSEP <> doc + else doc + + pprAsmCLbl (ForeignLabel fs (Just sz) _ _) + | platformOS platform == OSMinGW32 + -- In asm mode, we need to put the suffix on a stdcall ForeignLabel. + -- (The C compiler does this itself). + = ftext fs <> char '@' <> int sz + pprAsmCLbl lbl = pprCLbl dflags lbl + +pprCLbl :: DynFlags -> CLabel -> SDoc +pprCLbl dflags = \case + (StringLitLabel u) -> pprUniqueAlways u <> text "_str" + (SRTLabel u) -> tempLabelPrefixOrUnderscore <> pprUniqueAlways u <> pp_cSEP <> text "srt" + (LargeBitmapLabel u) -> tempLabelPrefixOrUnderscore + <> char 'b' <> pprUniqueAlways u <> pp_cSEP <> text "btm" + -- Some bitmaps for tuple constructors have a numeric tag (e.g. '7') + -- until that gets resolved we'll just force them to start + -- with a letter so the label will be legal assembly code. + + (CmmLabel _ str CmmCode) -> ftext str + (CmmLabel _ str CmmData) -> ftext str + (CmmLabel _ str CmmPrimCall) -> ftext str + + (LocalBlockLabel u) -> tempLabelPrefixOrUnderscore <> text "blk_" <> pprUniqueAlways u + + (RtsLabel (RtsApFast str)) -> ftext str <> text "_fast" + + (RtsLabel (RtsSelectorInfoTable upd_reqd offset)) -> ASSERT(offset >= 0 && offset <= mAX_SPEC_SELECTEE_SIZE dflags) hcat [text "stg_sel_", text (show offset), ptext (if upd_reqd @@ -1262,8 +1255,7 @@ pprCLbl (RtsLabel (RtsSelectorInfoTable upd_reqd offset)) else (sLit "_noupd_info")) ] -pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset)) - = sdocWithDynFlags $ \dflags -> + (RtsLabel (RtsSelectorEntry upd_reqd offset)) -> ASSERT(offset >= 0 && offset <= mAX_SPEC_SELECTEE_SIZE dflags) hcat [text "stg_sel_", text (show offset), ptext (if upd_reqd @@ -1271,8 +1263,7 @@ pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset)) else (sLit "_noupd_entry")) ] -pprCLbl (RtsLabel (RtsApInfoTable upd_reqd arity)) - = sdocWithDynFlags $ \dflags -> + (RtsLabel (RtsApInfoTable upd_reqd arity)) -> ASSERT(arity > 0 && arity <= mAX_SPEC_AP_SIZE dflags) hcat [text "stg_ap_", text (show arity), ptext (if upd_reqd @@ -1280,8 +1271,7 @@ pprCLbl (RtsLabel (RtsApInfoTable upd_reqd arity)) else (sLit "_noupd_info")) ] -pprCLbl (RtsLabel (RtsApEntry upd_reqd arity)) - = sdocWithDynFlags $ \dflags -> + (RtsLabel (RtsApEntry upd_reqd arity)) -> ASSERT(arity > 0 && arity <= mAX_SPEC_AP_SIZE dflags) hcat [text "stg_ap_", text (show arity), ptext (if upd_reqd @@ -1289,44 +1279,29 @@ pprCLbl (RtsLabel (RtsApEntry upd_reqd arity)) else (sLit "_noupd_entry")) ] -pprCLbl (CmmLabel _ fs CmmInfo) - = ftext fs <> text "_info" - -pprCLbl (CmmLabel _ fs CmmEntry) - = ftext fs <> text "_entry" - -pprCLbl (CmmLabel _ fs CmmRetInfo) - = ftext fs <> text "_info" - -pprCLbl (CmmLabel _ fs CmmRet) - = ftext fs <> text "_ret" - -pprCLbl (CmmLabel _ fs CmmClosure) - = ftext fs <> text "_closure" - -pprCLbl (RtsLabel (RtsPrimOp primop)) - = text "stg_" <> ppr primop - -pprCLbl (RtsLabel (RtsSlowFastTickyCtr pat)) - = text "SLOW_CALL_fast_" <> text pat <> ptext (sLit "_ctr") + (CmmLabel _ fs CmmInfo) -> ftext fs <> text "_info" + (CmmLabel _ fs CmmEntry) -> ftext fs <> text "_entry" + (CmmLabel _ fs CmmRetInfo) -> ftext fs <> text "_info" + (CmmLabel _ fs CmmRet) -> ftext fs <> text "_ret" + (CmmLabel _ fs CmmClosure) -> ftext fs <> text "_closure" -pprCLbl (ForeignLabel str _ _ _) - = ftext str + (RtsLabel (RtsPrimOp primop)) -> text "stg_" <> ppr primop + (RtsLabel (RtsSlowFastTickyCtr pat)) -> + text "SLOW_CALL_fast_" <> text pat <> ptext (sLit "_ctr") -pprCLbl (IdLabel name _cafs flavor) = - internalNamePrefix name <> ppr name <> ppIdFlavor flavor + (ForeignLabel str _ _ _) -> ftext str -pprCLbl (CC_Label cc) = ppr cc -pprCLbl (CCS_Label ccs) = ppr ccs + (IdLabel name _cafs flavor) -> internalNamePrefix name <> ppr name <> ppIdFlavor flavor -pprCLbl (HpcTicksLabel mod) - = text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") + (CC_Label cc) -> ppr cc + (CCS_Label ccs) -> ppr ccs + (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") -pprCLbl (AsmTempLabel {}) = panic "pprCLbl AsmTempLabel" -pprCLbl (AsmTempDerivedLabel {})= panic "pprCLbl AsmTempDerivedLabel" -pprCLbl (DynamicLinkerLabel {}) = panic "pprCLbl DynamicLinkerLabel" -pprCLbl (PicBaseLabel {}) = panic "pprCLbl PicBaseLabel" -pprCLbl (DeadStripPreventer {}) = panic "pprCLbl DeadStripPreventer" + (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" + (AsmTempDerivedLabel {}) -> panic "pprCLbl AsmTempDerivedLabel" + (DynamicLinkerLabel {}) -> panic "pprCLbl DynamicLinkerLabel" + (PicBaseLabel {}) -> panic "pprCLbl PicBaseLabel" + (DeadStripPreventer {}) -> panic "pprCLbl DeadStripPreventer" ppIdFlavor :: IdLabelInfo -> SDoc ppIdFlavor x = pp_cSEP <> text ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -31,6 +31,8 @@ import GHC.Runtime.Heap.Layout import GHC.Types.Unique.Supply import GHC.Types.CostCentre import GHC.StgToCmm.Heap +import GHC.CmmToAsm.Monad +import GHC.CmmToAsm.Config import Control.Monad import Data.Map.Strict (Map) @@ -925,6 +927,7 @@ oneSRT dflags staticFuns lbls caf_lbls isCAF cafs static_data = do topSRT <- get let + config = initConfig dflags srtMap = moduleSRTMap topSRT blockids = getBlockLabels lbls @@ -1024,11 +1027,11 @@ oneSRT dflags staticFuns lbls caf_lbls isCAF cafs static_data = do -- when dynamic linking is used we cannot guarantee that the offset -- between the SRT and the info table will fit in the offset field. -- Consequently we build a singleton SRT in in this case. - not (labelDynamic dflags this_mod lbl) + not (labelDynamic config this_mod lbl) -- MachO relocations can't express offsets between compilation units at -- all, so we are always forced to build a singleton SRT in this case. - && (not (osMachOTarget $ platformOS $ targetPlatform dflags) + && (not (osMachOTarget $ platformOS $ ncgPlatform config) || isLocalCLabel this_mod lbl) -> do -- If we have a static function closure, then it becomes the ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -162,35 +162,36 @@ nativeCodeGen :: forall a . DynFlags -> Module -> ModLocation -> Handle -> UniqS -> Stream IO RawCmmGroup a -> IO a nativeCodeGen dflags this_mod modLoc h us cmms - = let platform = targetPlatform dflags + = let config = initConfig dflags + platform = ncgPlatform config nCG' :: ( Outputable statics, Outputable instr , Outputable jumpDest, Instruction instr) => NcgImpl statics instr jumpDest -> IO a nCG' ncgImpl = nativeCodeGen' dflags this_mod modLoc ncgImpl h us cmms in case platformArch platform of - ArchX86 -> nCG' (x86NcgImpl dflags) - ArchX86_64 -> nCG' (x86_64NcgImpl dflags) - ArchPPC -> nCG' (ppcNcgImpl dflags) + ArchX86 -> nCG' (x86NcgImpl config) + ArchX86_64 -> nCG' (x86_64NcgImpl config) + ArchPPC -> nCG' (ppcNcgImpl config) ArchS390X -> panic "nativeCodeGen: No NCG for S390X" - ArchSPARC -> nCG' (sparcNcgImpl dflags) + ArchSPARC -> nCG' (sparcNcgImpl config) ArchSPARC64 -> panic "nativeCodeGen: No NCG for SPARC64" ArchARM {} -> panic "nativeCodeGen: No NCG for ARM" ArchARM64 -> panic "nativeCodeGen: No NCG for ARM64" - ArchPPC_64 _ -> nCG' (ppcNcgImpl dflags) + ArchPPC_64 _ -> nCG' (ppcNcgImpl config) ArchAlpha -> panic "nativeCodeGen: No NCG for Alpha" ArchMipseb -> panic "nativeCodeGen: No NCG for mipseb" ArchMipsel -> panic "nativeCodeGen: No NCG for mipsel" ArchUnknown -> panic "nativeCodeGen: No NCG for unknown arch" ArchJavaScript-> panic "nativeCodeGen: No NCG for JavaScript" -x86NcgImpl :: DynFlags -> NcgImpl (Alignment, RawCmmStatics) +x86NcgImpl :: NCGConfig -> NcgImpl (Alignment, RawCmmStatics) X86.Instr.Instr X86.Instr.JumpDest -x86NcgImpl dflags - = (x86_64NcgImpl dflags) +x86NcgImpl config + = (x86_64NcgImpl config) -x86_64NcgImpl :: DynFlags -> NcgImpl (Alignment, RawCmmStatics) +x86_64NcgImpl :: NCGConfig -> NcgImpl (Alignment, RawCmmStatics) X86.Instr.Instr X86.Instr.JumpDest -x86_64NcgImpl dflags +x86_64NcgImpl config = NcgImpl { ncgConfig = config ,cmmTopCodeGen = X86.CodeGen.cmmTopCodeGen @@ -209,11 +210,10 @@ x86_64NcgImpl dflags ,invertCondBranches = X86.CodeGen.invertCondBranches } where - config = initConfig dflags platform = ncgPlatform config -ppcNcgImpl :: DynFlags -> NcgImpl RawCmmStatics PPC.Instr.Instr PPC.RegInfo.JumpDest -ppcNcgImpl dflags +ppcNcgImpl :: NCGConfig -> NcgImpl RawCmmStatics PPC.Instr.Instr PPC.RegInfo.JumpDest +ppcNcgImpl config = NcgImpl { ncgConfig = config ,cmmTopCodeGen = PPC.CodeGen.cmmTopCodeGen @@ -232,11 +232,10 @@ ppcNcgImpl dflags ,invertCondBranches = \_ _ -> id } where - config = initConfig dflags platform = ncgPlatform config -sparcNcgImpl :: DynFlags -> NcgImpl RawCmmStatics SPARC.Instr.Instr SPARC.ShortcutJump.JumpDest -sparcNcgImpl dflags +sparcNcgImpl :: NCGConfig -> NcgImpl RawCmmStatics SPARC.Instr.Instr SPARC.ShortcutJump.JumpDest +sparcNcgImpl config = NcgImpl { ncgConfig = config ,cmmTopCodeGen = SPARC.CodeGen.cmmTopCodeGen @@ -255,7 +254,6 @@ sparcNcgImpl dflags ,invertCondBranches = \_ _ -> id } where - config = initConfig dflags platform = ncgPlatform config -- @@ -387,7 +385,8 @@ finishNativeGen dflags modLoc bufh@(BufHandle _ _ h) us ngs dump_stats (Linear.pprStats (concat (ngs_natives ngs)) linearStats) -- write out the imports - printSDocLn Pretty.LeftMode dflags h (mkCodeStyle AsmStyle) + let ctx = initSDocContext dflags (mkCodeStyle AsmStyle) + printSDocLn ctx Pretty.LeftMode h $ makeImportsDoc dflags (concat (ngs_imports ngs)) return us' where @@ -516,8 +515,8 @@ cmmNativeGens dflags this_mod modLoc ncgImpl h dbgMap = go emitNativeCode :: DynFlags -> BufHandle -> SDoc -> IO () emitNativeCode dflags h sdoc = do - {-# SCC "pprNativeCode" #-} bufLeftRenderSDoc dflags h - (mkCodeStyle AsmStyle) sdoc + let ctx = initSDocContext dflags (mkCodeStyle AsmStyle) + {-# SCC "pprNativeCode" #-} bufLeftRenderSDoc ctx h sdoc -- dump native code dumpIfSet_dyn dflags @@ -564,7 +563,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count -- cmm to cmm optimisations let (opt_cmm, imports) = {-# SCC "cmmToCmm" #-} - cmmToCmm dflags this_mod fixed_cmm + cmmToCmm config this_mod fixed_cmm dumpIfSet_dyn dflags Opt_D_dump_opt_cmm "Optimised Cmm" FormatCMM @@ -1066,10 +1065,10 @@ Ideas for other things we could do (put these in Hoopl please!): temp assignments, and certain assigns to mem...) -} -cmmToCmm :: DynFlags -> Module -> RawCmmDecl -> (RawCmmDecl, [CLabel]) +cmmToCmm :: NCGConfig -> Module -> RawCmmDecl -> (RawCmmDecl, [CLabel]) cmmToCmm _ _ top@(CmmData _ _) = (top, []) -cmmToCmm dflags this_mod (CmmProc info lbl live graph) - = runCmmOpt dflags this_mod $ +cmmToCmm config this_mod (CmmProc info lbl live graph) + = runCmmOpt config this_mod $ do blocks' <- mapM cmmBlockConFold (toBlockList graph) return $ CmmProc info lbl live (ofBlockList (g_entry graph) blocks') @@ -1086,7 +1085,7 @@ pattern OptMResult x y = (# x, y #) data OptMResult a = OptMResult !a ![CLabel] deriving (Functor) #endif -newtype CmmOptM a = CmmOptM (DynFlags -> Module -> [CLabel] -> OptMResult a) +newtype CmmOptM a = CmmOptM (NCGConfig -> Module -> [CLabel] -> OptMResult a) deriving (Functor) instance Applicative CmmOptM where @@ -1095,11 +1094,11 @@ instance Applicative CmmOptM where instance Monad CmmOptM where (CmmOptM f) >>= g = - CmmOptM $ \dflags this_mod imports0 -> - case f dflags this_mod imports0 of + CmmOptM $ \config this_mod imports0 -> + case f config this_mod imports0 of OptMResult x imports1 -> case g x of - CmmOptM g' -> g' dflags this_mod imports1 + CmmOptM g' -> g' config this_mod imports1 instance CmmMakeDynamicReferenceM CmmOptM where addImport = addImportCmmOpt @@ -1108,12 +1107,12 @@ instance CmmMakeDynamicReferenceM CmmOptM where addImportCmmOpt :: CLabel -> CmmOptM () addImportCmmOpt lbl = CmmOptM $ \_ _ imports -> OptMResult () (lbl:imports) -instance HasDynFlags CmmOptM where - getDynFlags = CmmOptM $ \dflags _ imports -> OptMResult dflags imports +getCmmOptConfig :: CmmOptM NCGConfig +getCmmOptConfig = CmmOptM $ \config _ imports -> OptMResult config imports -runCmmOpt :: DynFlags -> Module -> CmmOptM a -> (a, [CLabel]) -runCmmOpt dflags this_mod (CmmOptM f) = - case f dflags this_mod [] of +runCmmOpt :: NCGConfig -> Module -> CmmOptM a -> (a, [CLabel]) +runCmmOpt config this_mod (CmmOptM f) = + case f config this_mod [] of OptMResult result imports -> (result, imports) cmmBlockConFold :: CmmBlock -> CmmOptM CmmBlock @@ -1177,29 +1176,26 @@ cmmStmtConFold stmt cmmExprConFold :: ReferenceKind -> CmmExpr -> CmmOptM CmmExpr cmmExprConFold referenceKind expr = do - dflags <- getDynFlags + config <- getCmmOptConfig - -- With -O1 and greater, the cmmSink pass does constant-folding, so - -- we don't need to do it again here. - let expr' = if optLevel dflags >= 1 + let expr' = if not (ncgDoConstantFolding config) then expr - else cmmExprCon dflags expr + else cmmExprCon config expr cmmExprNative referenceKind expr' -cmmExprCon :: DynFlags -> CmmExpr -> CmmExpr -cmmExprCon dflags (CmmLoad addr rep) = CmmLoad (cmmExprCon dflags addr) rep -cmmExprCon dflags (CmmMachOp mop args) - = cmmMachOpFold platform mop (map (cmmExprCon dflags) args) - where platform = targetPlatform dflags +cmmExprCon :: NCGConfig -> CmmExpr -> CmmExpr +cmmExprCon config (CmmLoad addr rep) = CmmLoad (cmmExprCon config addr) rep +cmmExprCon config (CmmMachOp mop args) + = cmmMachOpFold (ncgPlatform config) mop (map (cmmExprCon config) args) cmmExprCon _ other = other -- handles both PIC and non-PIC cases... a very strange mixture -- of things to do. cmmExprNative :: ReferenceKind -> CmmExpr -> CmmOptM CmmExpr cmmExprNative referenceKind expr = do - dflags <- getDynFlags - let platform = targetPlatform dflags + config <- getCmmOptConfig + let platform = ncgPlatform config arch = platformArch platform case expr of CmmLoad addr rep @@ -1218,10 +1214,10 @@ cmmExprNative referenceKind expr = do CmmLit (CmmLabel lbl) -> do - cmmMakeDynamicReference dflags referenceKind lbl + cmmMakeDynamicReference config referenceKind lbl CmmLit (CmmLabelOff lbl off) -> do - dynRef <- cmmMakeDynamicReference dflags referenceKind lbl + dynRef <- cmmMakeDynamicReference config referenceKind lbl -- need to optimize here, since it's late return $ cmmMachOpFold platform (MO_Add (wordWidth platform)) [ dynRef, @@ -1232,15 +1228,15 @@ cmmExprNative referenceKind expr = do -- to use the register table, so we replace these registers -- with the corresponding labels: CmmReg (CmmGlobal EagerBlackholeInfo) - | arch == ArchPPC && not (positionIndependent dflags) + | arch == ArchPPC && not (ncgPIC config) -> cmmExprNative referenceKind $ CmmLit (CmmLabel (mkCmmCodeLabel rtsUnitId (fsLit "__stg_EAGER_BLACKHOLE_info"))) CmmReg (CmmGlobal GCEnter1) - | arch == ArchPPC && not (positionIndependent dflags) + | arch == ArchPPC && not (ncgPIC config) -> cmmExprNative referenceKind $ CmmLit (CmmLabel (mkCmmCodeLabel rtsUnitId (fsLit "__stg_gc_enter_1"))) CmmReg (CmmGlobal GCFun) - | arch == ArchPPC && not (positionIndependent dflags) + | arch == ArchPPC && not (ncgPIC config) -> cmmExprNative referenceKind $ CmmLit (CmmLabel (mkCmmCodeLabel rtsUnitId (fsLit "__stg_gc_fun"))) ===================================== compiler/GHC/CmmToAsm/Config.hs ===================================== @@ -9,21 +9,28 @@ where import GhcPrelude import GHC.Platform import GHC.Cmm.Type (Width(..)) +import GHC.Types.Module -- | Native code generator configuration data NCGConfig = NCGConfig - { ncgPlatform :: !Platform -- ^ Target platform - , ncgProcAlignment :: !(Maybe Int) -- ^ Mandatory proc alignment - , ncgDebugLevel :: !Int -- ^ Debug level - , ncgExternalDynamicRefs :: !Bool -- ^ Generate code to link against dynamic libraries - , ncgPIC :: !Bool -- ^ Enable Position-Independent Code - , ncgSplitSections :: !Bool -- ^ Split sections - , ncgSpillPreallocSize :: !Int -- ^ Size in bytes of the pre-allocated spill space on the C stack - , ncgRegsIterative :: !Bool - , ncgAsmLinting :: !Bool -- ^ Perform ASM linting pass - , ncgDumpRegAllocStages :: !Bool - , ncgDumpAsmStats :: !Bool - , ncgDumpAsmConflicts :: !Bool + { ncgPlatform :: !Platform -- ^ Target platform + , ncgUnitId :: UnitId -- ^ Target unit ID + , ncgProcAlignment :: !(Maybe Int) -- ^ Mandatory proc alignment + , ncgDebugLevel :: !Int -- ^ Debug level + , ncgExternalDynamicRefs :: !Bool -- ^ Generate code to link against dynamic libraries + , ncgPIC :: !Bool -- ^ Enable Position-Independent Code + , ncgInlineThresholdMemcpy :: !Word -- ^ If inlining `memcpy` produces less than this threshold (in pseudo-instruction unit), do it + , ncgInlineThresholdMemset :: !Word -- ^ Ditto for `memset` + , ncgSplitSections :: !Bool -- ^ Split sections + , ncgSpillPreallocSize :: !Int -- ^ Size in bytes of the pre-allocated spill space on the C stack + , ncgRegsIterative :: !Bool + , ncgAsmLinting :: !Bool -- ^ Perform ASM linting pass + , ncgDoConstantFolding :: !Bool -- ^ Perform CMM constant folding + , ncgSseVersion :: Maybe SseVersion -- ^ (x86) SSE instructions + , ncgBmiVersion :: Maybe BmiVersion -- ^ (x86) BMI instructions + , ncgDumpRegAllocStages :: !Bool + , ncgDumpAsmStats :: !Bool + , ncgDumpAsmConflicts :: !Bool } -- | Return Word size ===================================== compiler/GHC/CmmToAsm/Monad.hs ===================================== @@ -148,18 +148,46 @@ mkNatM_State us delta dflags this_mod -- | Initialize the native code generator configuration from the DynFlags initConfig :: DynFlags -> NCGConfig initConfig dflags = NCGConfig - { ncgPlatform = targetPlatform dflags - , ncgProcAlignment = cmmProcAlignment dflags - , ncgDebugLevel = debugLevel dflags - , ncgExternalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags - , ncgPIC = positionIndependent dflags - , ncgSplitSections = gopt Opt_SplitSections dflags - , ncgSpillPreallocSize = rESERVED_C_STACK_BYTES dflags - , ncgRegsIterative = gopt Opt_RegsIterative dflags - , ncgAsmLinting = gopt Opt_DoAsmLinting dflags - , ncgDumpRegAllocStages = dopt Opt_D_dump_asm_regalloc_stages dflags - , ncgDumpAsmStats = dopt Opt_D_dump_asm_stats dflags - , ncgDumpAsmConflicts = dopt Opt_D_dump_asm_conflicts dflags + { ncgPlatform = targetPlatform dflags + , ncgUnitId = thisPackage dflags + , ncgProcAlignment = cmmProcAlignment dflags + , ncgDebugLevel = debugLevel dflags + , ncgExternalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags + , ncgPIC = positionIndependent dflags + , ncgInlineThresholdMemcpy = fromIntegral $ maxInlineMemcpyInsns dflags + , ncgInlineThresholdMemset = fromIntegral $ maxInlineMemsetInsns dflags + , ncgSplitSections = gopt Opt_SplitSections dflags + , ncgSpillPreallocSize = rESERVED_C_STACK_BYTES dflags + , ncgRegsIterative = gopt Opt_RegsIterative dflags + , ncgAsmLinting = gopt Opt_DoAsmLinting dflags + + -- With -O1 and greater, the cmmSink pass does constant-folding, so + -- we don't need to do it again in the native code generator. + , ncgDoConstantFolding = optLevel dflags < 1 + + , ncgDumpRegAllocStages = dopt Opt_D_dump_asm_regalloc_stages dflags + , ncgDumpAsmStats = dopt Opt_D_dump_asm_stats dflags + , ncgDumpAsmConflicts = dopt Opt_D_dump_asm_conflicts dflags + , ncgBmiVersion = case platformArch (targetPlatform dflags) of + ArchX86_64 -> bmiVersion dflags + ArchX86 -> bmiVersion dflags + _ -> Nothing + + -- We Assume SSE1 and SSE2 operations are available on both + -- x86 and x86_64. Historically we didn't default to SSE2 and + -- SSE1 on x86, which results in defacto nondeterminism for how + -- rounding behaves in the associated x87 floating point instructions + -- because variations in the spill/fpu stack placement of arguments for + -- operations would change the precision and final result of what + -- would otherwise be the same expressions with respect to single or + -- double precision IEEE floating point computations. + , ncgSseVersion = + let v | sseVersion dflags < Just SSE2 = Just SSE2 + | otherwise = sseVersion dflags + in case platformArch (targetPlatform dflags) of + ArchX86_64 -> v + ArchX86 -> v + _ -> Nothing } ===================================== compiler/GHC/CmmToAsm/PIC.hs ===================================== @@ -109,21 +109,20 @@ instance CmmMakeDynamicReferenceM NatM where cmmMakeDynamicReference :: CmmMakeDynamicReferenceM m - => DynFlags + => NCGConfig -> ReferenceKind -- whether this is the target of a jump -> CLabel -- the label -> m CmmExpr -cmmMakeDynamicReference dflags referenceKind lbl +cmmMakeDynamicReference config referenceKind lbl | Just _ <- dynamicLinkerLabelInfo lbl = return $ CmmLit $ CmmLabel lbl -- already processed it, pass through | otherwise = do this_mod <- getThisModule - let config = initConfig dflags - platform = ncgPlatform config + let platform = ncgPlatform config case howToAccessLabel - dflags + config (platformArch platform) (platformOS platform) this_mod @@ -215,9 +214,7 @@ data LabelAccessStyle | AccessViaSymbolPtr | AccessDirectly -howToAccessLabel - :: DynFlags -> Arch -> OS -> Module -> ReferenceKind -> CLabel -> LabelAccessStyle - +howToAccessLabel :: NCGConfig -> Arch -> OS -> Module -> ReferenceKind -> CLabel -> LabelAccessStyle -- Windows -- In Windows speak, a "module" is a set of objects linked into the @@ -240,15 +237,15 @@ howToAccessLabel -- into the same .exe file. In this case we always access symbols directly, -- and never use __imp_SYMBOL. -- -howToAccessLabel dflags _ OSMinGW32 this_mod _ lbl +howToAccessLabel config _ OSMinGW32 this_mod _ lbl -- Assume all symbols will be in the same PE, so just access them directly. - | not (gopt Opt_ExternalDynamicRefs dflags) + | not (ncgExternalDynamicRefs config) = AccessDirectly -- If the target symbol is in another PE we need to access it via the -- appropriate __imp_SYMBOL pointer. - | labelDynamic dflags this_mod lbl + | labelDynamic config this_mod lbl = AccessViaSymbolPtr -- Target symbol is in the same PE as the caller, so just access it directly. @@ -264,9 +261,9 @@ howToAccessLabel dflags _ OSMinGW32 this_mod _ lbl -- It is always possible to access something indirectly, -- even when it's not necessary. -- -howToAccessLabel dflags arch OSDarwin this_mod DataReference lbl +howToAccessLabel config arch OSDarwin this_mod DataReference lbl -- data access to a dynamic library goes via a symbol pointer - | labelDynamic dflags this_mod lbl + | labelDynamic config this_mod lbl = AccessViaSymbolPtr -- when generating PIC code, all cross-module data references must @@ -279,27 +276,27 @@ howToAccessLabel dflags arch OSDarwin this_mod DataReference lbl -- we'd need to pass the current Module all the way in to -- this function. | arch /= ArchX86_64 - , positionIndependent dflags && externallyVisibleCLabel lbl + , ncgPIC config && externallyVisibleCLabel lbl = AccessViaSymbolPtr | otherwise = AccessDirectly -howToAccessLabel dflags arch OSDarwin this_mod JumpReference lbl +howToAccessLabel config arch OSDarwin this_mod JumpReference lbl -- dyld code stubs don't work for tailcalls because the -- stack alignment is only right for regular calls. -- Therefore, we have to go via a symbol pointer: | arch == ArchX86 || arch == ArchX86_64 - , labelDynamic dflags this_mod lbl + , labelDynamic config this_mod lbl = AccessViaSymbolPtr -howToAccessLabel dflags arch OSDarwin this_mod _ lbl +howToAccessLabel config arch OSDarwin this_mod _ lbl -- Code stubs are the usual method of choice for imported code; -- not needed on x86_64 because Apple's new linker, ld64, generates -- them automatically. | arch /= ArchX86_64 - , labelDynamic dflags this_mod lbl + , labelDynamic config this_mod lbl = AccessViaStub | otherwise @@ -310,7 +307,7 @@ howToAccessLabel dflags arch OSDarwin this_mod _ lbl -- AIX -- quite simple (for now) -howToAccessLabel _dflags _arch OSAIX _this_mod kind _lbl +howToAccessLabel _config _arch OSAIX _this_mod kind _lbl = case kind of DataReference -> AccessViaSymbolPtr CallReference -> AccessDirectly @@ -339,27 +336,27 @@ howToAccessLabel _ (ArchPPC_64 _) os _ kind _ -- regular calls are handled by the runtime linker _ -> AccessDirectly -howToAccessLabel dflags _ os _ _ _ +howToAccessLabel config _ os _ _ _ -- no PIC -> the dynamic linker does everything for us; -- if we don't dynamically link to Haskell code, -- it actually manages to do so without messing things up. | osElfTarget os - , not (positionIndependent dflags) && - not (gopt Opt_ExternalDynamicRefs dflags) + , not (ncgPIC config) && + not (ncgExternalDynamicRefs config) = AccessDirectly -howToAccessLabel dflags arch os this_mod DataReference lbl +howToAccessLabel config arch os this_mod DataReference lbl | osElfTarget os = case () of -- A dynamic label needs to be accessed via a symbol pointer. - _ | labelDynamic dflags this_mod lbl + _ | labelDynamic config this_mod lbl -> AccessViaSymbolPtr -- For PowerPC32 -fPIC, we have to access even static data -- via a symbol pointer (see below for an explanation why -- PowerPC32 Linux is especially broken). | arch == ArchPPC - , positionIndependent dflags + , ncgPIC config -> AccessViaSymbolPtr | otherwise @@ -378,26 +375,26 @@ howToAccessLabel dflags arch os this_mod DataReference lbl -- (AccessDirectly, because we get an implicit symbol stub) -- and calling functions from PIC code on non-i386 platforms (via a symbol stub) -howToAccessLabel dflags arch os this_mod CallReference lbl +howToAccessLabel config arch os this_mod CallReference lbl | osElfTarget os - , labelDynamic dflags this_mod lbl && not (positionIndependent dflags) + , labelDynamic config this_mod lbl && not (ncgPIC config) = AccessDirectly | osElfTarget os , arch /= ArchX86 - , labelDynamic dflags this_mod lbl - , positionIndependent dflags + , labelDynamic config this_mod lbl + , ncgPIC config = AccessViaStub -howToAccessLabel dflags _ os this_mod _ lbl +howToAccessLabel config _ os this_mod _ lbl | osElfTarget os - = if labelDynamic dflags this_mod lbl + = if labelDynamic config this_mod lbl then AccessViaSymbolPtr else AccessDirectly -- all other platforms -howToAccessLabel dflags _ _ _ _ _ - | not (positionIndependent dflags) +howToAccessLabel config _ _ _ _ _ + | not (ncgPIC config) = AccessDirectly | otherwise ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -33,7 +33,7 @@ import GHC.CmmToAsm.CPrim import GHC.CmmToAsm.Monad ( NatM, getNewRegNat, getNewLabelNat , getBlockIdNat, getPicBaseNat, getNewRegPairNat - , getPicBaseMaybeNat, getPlatform, initConfig + , getPicBaseMaybeNat, getPlatform, getConfig ) import GHC.CmmToAsm.Instr import GHC.CmmToAsm.PIC @@ -57,7 +57,6 @@ import GHC.Cmm.Dataflow.Graph -- The rest: import OrdList import Outputable -import GHC.Driver.Session import Control.Monad ( mapAndUnzipM, when ) import Data.Bits @@ -149,7 +148,7 @@ stmtsToInstrs stmts stmtToInstrs :: CmmNode e x -> NatM InstrBlock stmtToInstrs stmt = do - dflags <- getDynFlags + config <- getConfig platform <- getPlatform case stmt of CmmComment s -> return (unitOL (COMMENT s)) @@ -180,7 +179,7 @@ stmtToInstrs stmt = do b1 <- genCondJump true arg prediction b2 <- genBranch false return (b1 `appOL` b2) - CmmSwitch arg ids -> genSwitch dflags arg ids + CmmSwitch arg ids -> genSwitch config arg ids CmmCall { cml_target = arg , cml_args_regs = gregs } -> genJump arg (jumpRegs platform gregs) _ -> @@ -404,10 +403,10 @@ iselExpr64 expr getRegister :: CmmExpr -> NatM Register -getRegister e = do dflags <- getDynFlags - getRegister' dflags (targetPlatform dflags) e +getRegister e = do config <- getConfig + getRegister' config (ncgPlatform config) e -getRegister' :: DynFlags -> Platform -> CmmExpr -> NatM Register +getRegister' :: NCGConfig -> Platform -> CmmExpr -> NatM Register getRegister' _ platform (CmmReg (CmmGlobal PicBaseReg)) | OSAIX <- platformOS platform = do @@ -424,8 +423,8 @@ getRegister' _ platform (CmmReg reg) = return (Fixed (cmmTypeFormat (cmmRegType platform reg)) (getRegisterReg platform reg) nilOL) -getRegister' dflags platform tree@(CmmRegOff _ _) - = getRegister' dflags platform (mangleIndexTree platform tree) +getRegister' config platform tree@(CmmRegOff _ _) + = getRegister' config platform (mangleIndexTree platform tree) -- for 32-bit architectures, support some 64 -> 32 bit conversions: -- TO_W_(x), TO_W_(x >> 32) @@ -509,7 +508,7 @@ getRegister' _ _ (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode DS mem return (Any II64 (\dst -> addr_code `snocOL` LA II32 dst addr)) -getRegister' dflags platform (CmmMachOp mop [x]) -- unary MachOps +getRegister' config platform (CmmMachOp mop [x]) -- unary MachOps = case mop of MO_Not rep -> triv_ucode_int rep NOT @@ -539,7 +538,7 @@ getRegister' dflags platform (CmmMachOp mop [x]) -- unary MachOps triv_ucode_float width instr = trivialUCode (floatFormat width) instr x conversionNop new_format expr - = do e_code <- getRegister' dflags platform expr + = do e_code <- getRegister' config platform expr return (swizzleRegisterRep e_code new_format) clearLeft from to @@ -662,9 +661,9 @@ getRegister' _ _ (CmmLit (CmmInt i rep)) in return (Any (intFormat rep) code) -getRegister' dflags _ (CmmLit (CmmFloat f frep)) = do +getRegister' config _ (CmmLit (CmmFloat f frep)) = do lbl <- getNewLabelNat - dynRef <- cmmMakeDynamicReference dflags DataReference lbl + dynRef <- cmmMakeDynamicReference config DataReference lbl Amode addr addr_code <- getAmode D dynRef let format = floatFormat frep code dst = @@ -673,7 +672,7 @@ getRegister' dflags _ (CmmLit (CmmFloat f frep)) = do `consOL` (addr_code `snocOL` LD format dst addr) return (Any format code) -getRegister' dflags platform (CmmLit lit) +getRegister' config platform (CmmLit lit) | target32Bit platform = let rep = cmmLitType platform lit imm = litToImm lit @@ -684,7 +683,7 @@ getRegister' dflags platform (CmmLit lit) in return (Any (cmmTypeFormat rep) code) | otherwise = do lbl <- getNewLabelNat - dynRef <- cmmMakeDynamicReference dflags DataReference lbl + dynRef <- cmmMakeDynamicReference config DataReference lbl Amode addr addr_code <- getAmode D dynRef let rep = cmmLitType platform lit format = cmmTypeFormat rep @@ -1031,8 +1030,8 @@ assignMem_IntCode pk addr src = do -- dst is a reg, but src could be anything assignReg_IntCode _ reg src = do - dflags <- getDynFlags - let dst = getRegisterReg (targetPlatform dflags) reg + platform <- getPlatform + let dst = getRegisterReg platform reg r <- getRegister src return $ case r of Any _ code -> code dst @@ -1053,8 +1052,8 @@ genJump (CmmLit (CmmLabel lbl)) regs genJump tree gregs = do - dflags <- getDynFlags - genJump' tree (platformToGCP (targetPlatform dflags)) gregs + platform <- getPlatform + genJump' tree (platformToGCP platform) gregs genJump' :: CmmExpr -> GenCCallPlatform -> [Reg] -> NatM InstrBlock @@ -1132,9 +1131,8 @@ genCCall (PrimTarget (MO_Prefetch_Data _)) _ _ = return $ nilOL genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] - = do dflags <- getDynFlags - let platform = targetPlatform dflags - fmt = intFormat width + = do platform <- getPlatform + let fmt = intFormat width reg_dst = getRegisterReg platform (CmmLocal dst) (instr, n_code) <- case amop of AMO_Add -> getSomeRegOrImm ADD True reg_dst @@ -1184,9 +1182,8 @@ genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] return (op dst dst (RIReg n_reg), n_code) genCCall (PrimTarget (MO_AtomicRead width)) [dst] [addr] - = do dflags <- getDynFlags - let platform = targetPlatform dflags - fmt = intFormat width + = do platform <- getPlatform + let fmt = intFormat width reg_dst = getRegisterReg platform (CmmLocal dst) form = if widthInBits width == 64 then DS else D Amode addr_reg addr_code <- getAmode form addr @@ -1216,9 +1213,8 @@ genCCall (PrimTarget (MO_AtomicWrite width)) [] [addr, val] = do return $ unitOL(HWSYNC) `appOL` code genCCall (PrimTarget (MO_Clz width)) [dst] [src] - = do dflags <- getDynFlags - let platform = targetPlatform dflags - reg_dst = getRegisterReg platform (CmmLocal dst) + = do platform <- getPlatform + let reg_dst = getRegisterReg platform (CmmLocal dst) if target32Bit platform && width == W64 then do ChildCode64 code vr_lo <- iselExpr64 src @@ -1268,9 +1264,8 @@ genCCall (PrimTarget (MO_Clz width)) [dst] [src] return $ s_code `appOL` pre `appOL` cntlz `appOL` post genCCall (PrimTarget (MO_Ctz width)) [dst] [src] - = do dflags <- getDynFlags - let platform = targetPlatform dflags - reg_dst = getRegisterReg platform (CmmLocal dst) + = do platform <- getPlatform + let reg_dst = getRegisterReg platform (CmmLocal dst) if target32Bit platform && width == W64 then do let format = II32 @@ -1334,8 +1329,7 @@ genCCall (PrimTarget (MO_Ctz width)) [dst] [src] ] genCCall target dest_regs argsAndHints - = do dflags <- getDynFlags - let platform = targetPlatform dflags + = do platform <- getPlatform case target of PrimTarget (MO_S_QuotRem width) -> divOp1 platform True width dest_regs argsAndHints @@ -1354,7 +1348,8 @@ genCCall target dest_regs argsAndHints dest_regs argsAndHints PrimTarget MO_F64_Fabs -> fabs platform dest_regs argsAndHints PrimTarget MO_F32_Fabs -> fabs platform dest_regs argsAndHints - _ -> genCCall' dflags (platformToGCP platform) + _ -> do config <- getConfig + genCCall' config (platformToGCP platform) target dest_regs argsAndHints where divOp1 platform signed width [res_q, res_r] [arg_x, arg_y] = do let reg_q = getRegisterReg platform (CmmLocal res_q) @@ -1586,7 +1581,7 @@ platformToGCP platform genCCall' - :: DynFlags + :: NCGConfig -> GenCCallPlatform -> ForeignTarget -- function to call -> [CmmFormal] -- where to put the result @@ -1639,7 +1634,7 @@ genCCall' -} -genCCall' dflags gcp target dest_regs args +genCCall' config gcp target dest_regs args = do (finalStack,passArgumentsCode,usedRegs) <- passArguments (zip3 args argReps argHints) @@ -1705,7 +1700,6 @@ genCCall' dflags gcp target dest_regs args `snocOL` BCTRL usedRegs `appOL` codeAfter) where - config = initConfig dflags platform = ncgPlatform config uses_pic_base_implicitly = do @@ -1777,7 +1771,7 @@ genCCall' dflags gcp target dest_regs args passArguments [] _ _ stackOffset accumCode accumUsed = return (stackOffset, accumCode, accumUsed) passArguments ((arg,arg_ty,_):args) gprs fprs stackOffset accumCode accumUsed | isWord64 arg_ty - && target32Bit (targetPlatform dflags) = + && target32Bit (ncgPlatform config) = do ChildCode64 code vr_lo <- iselExpr64 arg let vr_hi = getHiVRegFromLo vr_lo @@ -1945,8 +1939,7 @@ genCCall' dflags gcp target dest_regs args outOfLineMachOp mop = do - dflags <- getDynFlags - mopExpr <- cmmMakeDynamicReference dflags CallReference $ + mopExpr <- cmmMakeDynamicReference config CallReference $ mkForeignLabel functionName Nothing ForeignLabelInThisPackage IsFunction let mopLabelOrExpr = case mopExpr of CmmLit (CmmLabel lbl) -> Left lbl @@ -2041,8 +2034,8 @@ genCCall' dflags gcp target dest_regs args -- ----------------------------------------------------------------------------- -- Generating a table-branch -genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock -genSwitch dflags expr targets +genSwitch :: NCGConfig -> CmmExpr -> SwitchTargets -> NatM InstrBlock +genSwitch config expr targets | OSAIX <- platformOS platform = do (reg,e_code) <- getSomeReg (cmmOffset platform expr offset) @@ -2050,7 +2043,7 @@ genSwitch dflags expr targets sha = if target32Bit platform then 2 else 3 tmp <- getNewRegNat fmt lbl <- getNewLabelNat - dynRef <- cmmMakeDynamicReference dflags DataReference lbl + dynRef <- cmmMakeDynamicReference config DataReference lbl (tableReg,t_code) <- getSomeReg $ dynRef let code = e_code `appOL` t_code `appOL` toOL [ SL fmt tmp reg (RIImm (ImmInt sha)), @@ -2067,7 +2060,7 @@ genSwitch dflags expr targets sha = if target32Bit platform then 2 else 3 tmp <- getNewRegNat fmt lbl <- getNewLabelNat - dynRef <- cmmMakeDynamicReference dflags DataReference lbl + dynRef <- cmmMakeDynamicReference config DataReference lbl (tableReg,t_code) <- getSomeReg $ dynRef let code = e_code `appOL` t_code `appOL` toOL [ SL fmt tmp reg (RIImm (ImmInt sha)), @@ -2095,7 +2088,6 @@ genSwitch dflags expr targets where (offset, ids) = switchTargetsToTable targets platform = ncgPlatform config - config = initConfig dflags generateJumpTableForInstr :: NCGConfig -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) @@ -2334,9 +2326,9 @@ coerceInt2FP' ArchPPC fromRep toRep x = do lbl <- getNewLabelNat itmp <- getNewRegNat II32 ftmp <- getNewRegNat FF64 - dflags <- getDynFlags + config <- getConfig platform <- getPlatform - dynRef <- cmmMakeDynamicReference dflags DataReference lbl + dynRef <- cmmMakeDynamicReference config DataReference lbl Amode addr addr_code <- getAmode D dynRef let code' dst = code `appOL` maybe_exts `appOL` toOL [ ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -53,7 +53,6 @@ import GHC.CmmToAsm.CPrim -- The rest: import GHC.Types.Basic -import GHC.Driver.Session import FastString import OrdList import Outputable @@ -455,7 +454,7 @@ genCCall target dest_regs args let transfer_code = toOL (move_final vregs allArgRegs extraStackArgsHere) - dflags <- getDynFlags + platform <- getPlatform return $ argcode `appOL` move_sp_down `appOL` @@ -463,7 +462,7 @@ genCCall target dest_regs args callinsns `appOL` unitOL NOP `appOL` move_sp_up `appOL` - assign_code (targetPlatform dflags) dest_regs + assign_code platform dest_regs -- | Generate code to calculate an argument, and move it into one @@ -594,8 +593,8 @@ outOfLineMachOp mop = do let functionName = outOfLineMachOp_table mop - dflags <- getDynFlags - mopExpr <- cmmMakeDynamicReference dflags CallReference + config <- getConfig + mopExpr <- cmmMakeDynamicReference config CallReference $ mkForeignLabel functionName Nothing ForeignLabelInExternalPackage IsFunction let mopLabelOrExpr ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -104,26 +104,13 @@ is32BitPlatform = do sse2Enabled :: NatM Bool sse2Enabled = do - platform <- getPlatform - case platformArch platform of - -- We Assume SSE1 and SSE2 operations are available on both - -- x86 and x86_64. Historically we didn't default to SSE2 and - -- SSE1 on x86, which results in defacto nondeterminism for how - -- rounding behaves in the associated x87 floating point instructions - -- because variations in the spill/fpu stack placement of arguments for - -- operations would change the precision and final result of what - -- would otherwise be the same expressions with respect to single or - -- double precision IEEE floating point computations. - ArchX86_64 -> return True - ArchX86 -> return True - _ -> panic "trying to generate x86/x86_64 on the wrong platform" - + config <- getConfig + return (ncgSseVersion config >= Just SSE2) sse4_2Enabled :: NatM Bool sse4_2Enabled = do - dflags <- getDynFlags - return (isSse4_2Enabled dflags) - + config <- getConfig + return (ncgSseVersion config >= Just SSE42) cmmTopCodeGen :: RawCmmDecl @@ -1474,11 +1461,11 @@ memConstant :: Alignment -> CmmLit -> NatM Amode memConstant align lit = do lbl <- getNewLabelNat let rosection = Section ReadOnlyData lbl - dflags <- getDynFlags + config <- getConfig platform <- getPlatform (addr, addr_code) <- if target32Bit platform then do dynRef <- cmmMakeDynamicReference - dflags + config DataReference lbl Amode addr addr_code <- getAmode dynRef @@ -2122,10 +2109,10 @@ genCCall is32Bit (PrimTarget (MO_Ctz width)) [dst] [src] bid | otherwise = do code_src <- getAnyReg src - platform <- ncgPlatform <$> getConfig + config <- getConfig + let platform = ncgPlatform config let dst_r = getRegisterReg platform (CmmLocal dst) - dflags <- getDynFlags - if isBmi2Enabled dflags + if ncgBmiVersion config >= Just BMI2 then do src_r <- getNewRegNat (intFormat width) let instrs = appOL (code_src src_r) $ case width of @@ -2158,13 +2145,13 @@ genCCall is32Bit (PrimTarget (MO_Ctz width)) [dst] [src] bid bw = widthInBits width genCCall bits mop dst args bid = do - dflags <- getDynFlags - instr <- genCCall' dflags bits mop dst args bid + config <- getConfig + instr <- genCCall' config bits mop dst args bid return (instr, Nothing) -- genCCall' handles cases not introducing new code blocks. genCCall' - :: DynFlags + :: NCGConfig -> Bool -- 32 bit platform? -> ForeignTarget -- function to call -> [CmmFormal] -- where to put the result @@ -2174,9 +2161,9 @@ genCCall' -- Unroll memcpy calls if the number of bytes to copy isn't too -- large. Otherwise, call C's memcpy. -genCCall' dflags _ (PrimTarget (MO_Memcpy align)) _ +genCCall' config _ (PrimTarget (MO_Memcpy align)) _ [dst, src, CmmLit (CmmInt n _)] _ - | fromInteger insns <= maxInlineMemcpyInsns dflags = do + | fromInteger insns <= ncgInlineThresholdMemcpy config = do code_dst <- getAnyReg dst dst_r <- getNewRegNat format code_src <- getAnyReg src @@ -2185,7 +2172,7 @@ genCCall' dflags _ (PrimTarget (MO_Memcpy align)) _ return $ code_dst dst_r `appOL` code_src src_r `appOL` go dst_r src_r tmp_r (fromInteger n) where - platform = targetPlatform dflags + platform = ncgPlatform config -- The number of instructions we will generate (approx). We need 2 -- instructions per move. insns = 2 * ((n + sizeBytes - 1) `div` sizeBytes) @@ -2224,12 +2211,12 @@ genCCall' dflags _ (PrimTarget (MO_Memcpy align)) _ dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone (ImmInteger (n - i)) -genCCall' dflags _ (PrimTarget (MO_Memset align)) _ +genCCall' config _ (PrimTarget (MO_Memset align)) _ [dst, CmmLit (CmmInt c _), CmmLit (CmmInt n _)] _ - | fromInteger insns <= maxInlineMemsetInsns dflags = do + | fromInteger insns <= ncgInlineThresholdMemset config = do code_dst <- getAnyReg dst dst_r <- getNewRegNat format if format == II64 && n >= 8 then do @@ -2242,7 +2229,7 @@ genCCall' dflags _ (PrimTarget (MO_Memset align)) _ return $ code_dst dst_r `appOL` go4 dst_r (fromInteger n) where - platform = targetPlatform dflags + platform = ncgPlatform config maxAlignment = wordAlignment platform -- only machine word wide MOVs are supported effectiveAlignment = min (alignmentOf align) maxAlignment format = intFormat . widthFromBytes $ alignmentBytes effectiveAlignment @@ -2348,10 +2335,10 @@ genCCall' _ is32Bit (PrimTarget (MO_BSwap width)) [dst] [src] _ = do where format = intFormat width -genCCall' dflags is32Bit (PrimTarget (MO_PopCnt width)) dest_regs@[dst] +genCCall' config is32Bit (PrimTarget (MO_PopCnt width)) dest_regs@[dst] args@[src] bid = do sse4_2 <- sse4_2Enabled - platform <- ncgPlatform <$> getConfig + let platform = ncgPlatform config if sse4_2 then do code_src <- getAnyReg src src_r <- getNewRegNat format @@ -2369,20 +2356,20 @@ genCCall' dflags is32Bit (PrimTarget (MO_PopCnt width)) dest_regs@[dst] unitOL (MOVZxL II16 (OpReg dst_r) (OpReg dst_r)) else nilOL) else do - targetExpr <- cmmMakeDynamicReference dflags + targetExpr <- cmmMakeDynamicReference config CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn) - genCCall' dflags is32Bit target dest_regs args bid + genCCall' config is32Bit target dest_regs args bid where format = intFormat width lbl = mkCmmCodeLabel primUnitId (fsLit (popCntLabel width)) -genCCall' dflags is32Bit (PrimTarget (MO_Pdep width)) dest_regs@[dst] +genCCall' config is32Bit (PrimTarget (MO_Pdep width)) dest_regs@[dst] args@[src, mask] bid = do - platform <- ncgPlatform <$> getConfig - if isBmi2Enabled dflags + let platform = ncgPlatform config + if ncgBmiVersion config >= Just BMI2 then do code_src <- getAnyReg src code_mask <- getAnyReg mask src_r <- getNewRegNat format @@ -2402,20 +2389,20 @@ genCCall' dflags is32Bit (PrimTarget (MO_Pdep width)) dest_regs@[dst] unitOL (MOVZxL II16 (OpReg dst_r) (OpReg dst_r)) else nilOL) else do - targetExpr <- cmmMakeDynamicReference dflags + targetExpr <- cmmMakeDynamicReference config CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn) - genCCall' dflags is32Bit target dest_regs args bid + genCCall' config is32Bit target dest_regs args bid where format = intFormat width lbl = mkCmmCodeLabel primUnitId (fsLit (pdepLabel width)) -genCCall' dflags is32Bit (PrimTarget (MO_Pext width)) dest_regs@[dst] +genCCall' config is32Bit (PrimTarget (MO_Pext width)) dest_regs@[dst] args@[src, mask] bid = do - platform <- ncgPlatform <$> getConfig - if isBmi2Enabled dflags + let platform = ncgPlatform config + if ncgBmiVersion config >= Just BMI2 then do code_src <- getAnyReg src code_mask <- getAnyReg mask src_r <- getNewRegNat format @@ -2435,30 +2422,31 @@ genCCall' dflags is32Bit (PrimTarget (MO_Pext width)) dest_regs@[dst] unitOL (MOVZxL II16 (OpReg dst_r) (OpReg dst_r)) else nilOL) else do - targetExpr <- cmmMakeDynamicReference dflags + targetExpr <- cmmMakeDynamicReference config CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn) - genCCall' dflags is32Bit target dest_regs args bid + genCCall' config is32Bit target dest_regs args bid where format = intFormat width lbl = mkCmmCodeLabel primUnitId (fsLit (pextLabel width)) -genCCall' dflags is32Bit (PrimTarget (MO_Clz width)) dest_regs@[dst] args@[src] bid +genCCall' config is32Bit (PrimTarget (MO_Clz width)) dest_regs@[dst] args@[src] bid | is32Bit && width == W64 = do -- Fallback to `hs_clz64` on i386 - targetExpr <- cmmMakeDynamicReference dflags CallReference lbl + targetExpr <- cmmMakeDynamicReference config CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn) - genCCall' dflags is32Bit target dest_regs args bid + genCCall' config is32Bit target dest_regs args bid | otherwise = do code_src <- getAnyReg src - platform <- ncgPlatform <$> getConfig + config <- getConfig + let platform = ncgPlatform config let dst_r = getRegisterReg platform (CmmLocal dst) - if isBmi2Enabled dflags + if ncgBmiVersion config >= Just BMI2 then do src_r <- getNewRegNat (intFormat width) return $ appOL (code_src src_r) $ case width of @@ -2489,13 +2477,13 @@ genCCall' dflags is32Bit (PrimTarget (MO_Clz width)) dest_regs@[dst] args@[src] bw = widthInBits width lbl = mkCmmCodeLabel primUnitId (fsLit (clzLabel width)) -genCCall' dflags is32Bit (PrimTarget (MO_UF_Conv width)) dest_regs args bid = do - targetExpr <- cmmMakeDynamicReference dflags +genCCall' config is32Bit (PrimTarget (MO_UF_Conv width)) dest_regs args bid = do + targetExpr <- cmmMakeDynamicReference config CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn) - genCCall' dflags is32Bit target dest_regs args bid + genCCall' config is32Bit target dest_regs args bid where lbl = mkCmmCodeLabel primUnitId (fsLit (word2FloatLabel width)) @@ -3142,8 +3130,8 @@ outOfLineCmmOp :: BlockId -> CallishMachOp -> Maybe CmmFormal -> [CmmActual] -> NatM InstrBlock outOfLineCmmOp bid mop res args = do - dflags <- getDynFlags - targetExpr <- cmmMakeDynamicReference dflags CallReference lbl + config <- getConfig + targetExpr <- cmmMakeDynamicReference config CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [] [] CmmMayReturn) @@ -3252,7 +3240,6 @@ genSwitch :: CmmExpr -> SwitchTargets -> NatM InstrBlock genSwitch expr targets = do config <- getConfig - dflags <- getDynFlags let platform = ncgPlatform config if ncgPIC config then do @@ -3272,7 +3259,7 @@ genSwitch expr targets = do -- if L0 is not preceded by a non-anonymous label in its section. OSDarwin | not is32bit -> Section Text lbl _ -> Section ReadOnlyData lbl - dynRef <- cmmMakeDynamicReference dflags DataReference lbl + dynRef <- cmmMakeDynamicReference config DataReference lbl (tableReg,t_code) <- getSomeReg $ dynRef let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) (EAIndex reg (platformWordSizeInBytes platform)) (ImmInt 0)) ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -75,14 +75,14 @@ llvmCodeGen dflags h cmm_stream -- run code generation a <- runLlvm dflags (fromMaybe supportedLlvmVersion mb_ver) bufh $ - llvmCodeGen' (liftStream cmm_stream) + llvmCodeGen' dflags (liftStream cmm_stream) bFlush bufh return a -llvmCodeGen' :: Stream.Stream LlvmM RawCmmGroup a -> LlvmM a -llvmCodeGen' cmm_stream +llvmCodeGen' :: DynFlags -> Stream.Stream LlvmM RawCmmGroup a -> LlvmM a +llvmCodeGen' dflags cmm_stream = do -- Preamble renderLlvm header ghcInternalFunctions @@ -100,19 +100,19 @@ llvmCodeGen' cmm_stream return a where header :: SDoc - header = sdocWithDynFlags $ \dflags -> + header = let target = platformMisc_llvmTarget $ platformMisc dflags - in text ("target datalayout = \"" ++ getDataLayout dflags target ++ "\"") + in text ("target datalayout = \"" ++ getDataLayout (llvmConfig dflags) target ++ "\"") $+$ text ("target triple = \"" ++ target ++ "\"") - getDataLayout :: DynFlags -> String -> String - getDataLayout dflags target = - case lookup target (llvmTargets $ llvmConfig dflags) of + getDataLayout :: LlvmConfig -> String -> String + getDataLayout config target = + case lookup target (llvmTargets config) of Just (LlvmTarget {lDataLayout=dl}) -> dl Nothing -> pprPanic "Failed to lookup LLVM data layout" $ text "Target:" <+> text target $$ hang (text "Available targets:") 4 - (vcat $ map (text . fst) $ llvmTargets $ llvmConfig dflags) + (vcat $ map (text . fst) $ llvmTargets config) llvmGroupLlvmGens :: RawCmmGroup -> LlvmM () llvmGroupLlvmGens cmm = do ===================================== compiler/GHC/CmmToLlvm/Base.hs ===================================== @@ -447,8 +447,8 @@ renderLlvm sdoc = do -- Write to output dflags <- getDynFlags out <- getEnv envOutput - liftIO $ Outp.bufLeftRenderSDoc dflags out - (Outp.mkCodeStyle Outp.CStyle) sdoc + let ctx = initSDocContext dflags (Outp.mkCodeStyle Outp.CStyle) + liftIO $ Outp.bufLeftRenderSDoc ctx out sdoc -- Dump, if requested dumpIfSetLlvm Opt_D_dump_llvm "LLVM Code" FormatLLVM sdoc ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -277,10 +277,9 @@ outputForeignStubs_help fname doc_str header footer -- module; -- | Generate code to initialise cost centres -profilingInitCode :: Module -> CollectedCCs -> SDoc -profilingInitCode this_mod (local_CCs, singleton_CCSs) - = sdocWithDynFlags $ \dflags -> - if not (gopt Opt_SccProfilingOn dflags) +profilingInitCode :: DynFlags -> Module -> CollectedCCs -> SDoc +profilingInitCode dflags this_mod (local_CCs, singleton_CCSs) + = if not (gopt Opt_SccProfilingOn dflags) then empty else vcat $ map emit_cc_decl local_CCs ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1420,7 +1420,7 @@ hscGenHardCode hsc_env cgguts location output_filename = do let cost_centre_info = (S.toList local_ccs ++ caf_ccs, caf_cc_stacks) - prof_init = profilingInitCode this_mod cost_centre_info + prof_init = profilingInitCode dflags this_mod cost_centre_info foreign_stubs = foreign_stubs0 `appendStubC` prof_init ------------------ Code generation ------------------ ===================================== compiler/GHC/Driver/Packages.hs ===================================== @@ -2155,9 +2155,8 @@ displayInstalledUnitId pkgstate uid = fmap sourcePackageIdString (lookupInstalledPackage pkgstate uid) -- | Will the 'Name' come from a dynamically linked package? -isDynLinkName :: DynFlags -> Module -> Name -> Bool -isDynLinkName dflags this_mod name - | not (gopt Opt_ExternalDynamicRefs dflags) = False +isDynLinkName :: Platform -> Module -> Name -> Bool +isDynLinkName platform this_mod name | Just mod <- nameModule_maybe name -- Issue #8696 - when GHC is dynamically linked, it will attempt -- to load the dynamic dependencies of object files at compile @@ -2171,7 +2170,7 @@ isDynLinkName dflags this_mod name -- In the mean time, always force dynamic indirections to be -- generated: when the module name isn't the module being -- compiled, references are dynamic. - = case platformOS $ targetPlatform dflags of + = case platformOS platform of -- On Windows the hack for #8696 makes it unlinkable. -- As the entire setup of the code from Cmm down to the RTS expects -- the use of trampolines for the imported functions only when ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -230,7 +230,7 @@ module GHC.Driver.Session ( IncludeSpecs(..), addGlobalInclude, addQuoteInclude, flattenIncludes, -- * SDoc - initSDocContext, + initSDocContext, initDefaultSDocContext, -- * Make use of the Cmm CFG CfgWeights(..) @@ -1588,7 +1588,8 @@ defaultLogActionHPutStrDoc :: DynFlags -> Handle -> SDoc -> PprStyle -> IO () defaultLogActionHPutStrDoc dflags h d sty -- Don't add a newline at the end, so that successive -- calls to this log-action can output all on the same line - = printSDoc Pretty.PageMode dflags h sty d + = printSDoc ctx Pretty.PageMode h d + where ctx = initSDocContext dflags sty newtype FlushOut = FlushOut (IO ()) @@ -5053,13 +5054,6 @@ setUnsafeGlobalDynFlags = writeIORef v_unsafeGlobalDynFlags -- check if SSE is enabled, we might have x86-64 imply the -msse2 -- flag. -data SseVersion = SSE1 - | SSE2 - | SSE3 - | SSE4 - | SSE42 - deriving (Eq, Ord) - isSseEnabled :: DynFlags -> Bool isSseEnabled dflags = case platformArch (targetPlatform dflags) of ArchX86_64 -> True @@ -5105,10 +5099,6 @@ isAvx512pfEnabled dflags = avx512pf dflags -- ----------------------------------------------------------------------------- -- BMI2 -data BmiVersion = BMI1 - | BMI2 - deriving (Eq, Ord) - isBmiEnabled :: DynFlags -> Bool isBmiEnabled dflags = case platformArch (targetPlatform dflags) of ArchX86_64 -> bmiVersion dflags >= Just BMI1 @@ -5184,7 +5174,7 @@ emptyFilesToClean :: FilesToClean emptyFilesToClean = FilesToClean Set.empty Set.empty - +-- | Initialize the pretty-printing options initSDocContext :: DynFlags -> PprStyle -> SDocContext initSDocContext dflags style = SDC { sdocStyle = style @@ -5220,3 +5210,7 @@ initSDocContext dflags style = SDC , sdocImpredicativeTypes = xopt LangExt.ImpredicativeTypes dflags , sdocDynFlags = dflags } + +-- | Initialize the pretty-printing options using the default user style +initDefaultSDocContext :: DynFlags -> SDocContext +initDefaultSDocContext dflags = initSDocContext dflags (defaultUserStyle dflags) ===================================== compiler/GHC/Driver/Session.hs-boot ===================================== @@ -8,7 +8,6 @@ data DynFlags targetPlatform :: DynFlags -> Platform pprUserLength :: DynFlags -> Int -pprCols :: DynFlags -> Int unsafeGlobalDynFlags :: DynFlags hasPprDebug :: DynFlags -> Bool hasNoDebugOutput :: DynFlags -> Bool ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -95,7 +95,8 @@ import Outputable import FastString import Bag import Util -import qualified GHC.Parser.Lexer as Lexer (P (..), ParseResult(..), unP, mkPState) +import qualified GHC.Parser.Lexer as Lexer (P (..), ParseResult(..), unP, mkPStatePure) +import GHC.Parser.Lexer (ParserFlags) import qualified GHC.Parser as Parser (parseStmt, parseModule, parseDeclaration, parseImport) import System.Directory @@ -879,44 +880,44 @@ parseName str = withSession $ \hsc_env -> liftIO $ ; hscTcRnLookupRdrName hsc_env lrdr_name } -- | Returns @True@ if passed string is a statement. -isStmt :: DynFlags -> String -> Bool -isStmt dflags stmt = - case parseThing Parser.parseStmt dflags stmt of +isStmt :: ParserFlags -> String -> Bool +isStmt pflags stmt = + case parseThing Parser.parseStmt pflags stmt of Lexer.POk _ _ -> True Lexer.PFailed _ -> False -- | Returns @True@ if passed string has an import declaration. -hasImport :: DynFlags -> String -> Bool -hasImport dflags stmt = - case parseThing Parser.parseModule dflags stmt of +hasImport :: ParserFlags -> String -> Bool +hasImport pflags stmt = + case parseThing Parser.parseModule pflags stmt of Lexer.POk _ thing -> hasImports thing Lexer.PFailed _ -> False where hasImports = not . null . hsmodImports . unLoc -- | Returns @True@ if passed string is an import declaration. -isImport :: DynFlags -> String -> Bool -isImport dflags stmt = - case parseThing Parser.parseImport dflags stmt of +isImport :: ParserFlags -> String -> Bool +isImport pflags stmt = + case parseThing Parser.parseImport pflags stmt of Lexer.POk _ _ -> True Lexer.PFailed _ -> False -- | Returns @True@ if passed string is a declaration but __/not a splice/__. -isDecl :: DynFlags -> String -> Bool -isDecl dflags stmt = do - case parseThing Parser.parseDeclaration dflags stmt of +isDecl :: ParserFlags -> String -> Bool +isDecl pflags stmt = do + case parseThing Parser.parseDeclaration pflags stmt of Lexer.POk _ thing -> case unLoc thing of SpliceD _ _ -> False _ -> True Lexer.PFailed _ -> False -parseThing :: Lexer.P thing -> DynFlags -> String -> Lexer.ParseResult thing -parseThing parser dflags stmt = do +parseThing :: Lexer.P thing -> ParserFlags -> String -> Lexer.ParseResult thing +parseThing parser pflags stmt = do let buf = stringToStringBuffer stmt loc = mkRealSrcLoc (fsLit "") 1 1 - Lexer.unP parser (Lexer.mkPState dflags buf loc) + Lexer.unP parser (Lexer.mkPStatePure pflags buf loc) getDocs :: GhcMonad m => Name ===================================== compiler/GHC/Runtime/Heap/Inspect.hs ===================================== @@ -865,7 +865,7 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0 -- This is a bit involved since we allow packing multiple fields -- within a single word. See also -- GHC.StgToCmm.Layout.mkVirtHeapOffsetsWithPadding - platform <- targetPlatform <$> getDynFlags + platform <- getPlatform let word_size = platformWordSizeInBytes platform endian = platformByteOrder platform size_b = primRepSizeB platform rep ===================================== compiler/GHC/Runtime/Linker.hs ===================================== @@ -127,15 +127,15 @@ modifyMbPLS_ :: DynLinker -> (Maybe PersistentLinkerState -> IO (Maybe PersistentLinkerState)) -> IO () modifyMbPLS_ dl f = modifyMVar_ (dl_mpls dl) f -emptyPLS :: DynFlags -> PersistentLinkerState -emptyPLS _ = PersistentLinkerState { - closure_env = emptyNameEnv, - itbl_env = emptyNameEnv, - pkgs_loaded = init_pkgs, - bcos_loaded = [], - objs_loaded = [], - temp_sos = [] } - +emptyPLS :: PersistentLinkerState +emptyPLS = PersistentLinkerState + { closure_env = emptyNameEnv + , itbl_env = emptyNameEnv + , pkgs_loaded = init_pkgs + , bcos_loaded = [] + , objs_loaded = [] + , temp_sos = [] + } -- Packages that don't need loading, because the compiler -- shares them with the interpreted program. -- @@ -280,7 +280,7 @@ reallyInitDynLinker :: HscEnv -> IO PersistentLinkerState reallyInitDynLinker hsc_env = do -- Initialise the linker state let dflags = hsc_dflags hsc_env - pls0 = emptyPLS dflags + pls0 = emptyPLS -- (a) initialise the C dynamic linker initObjLinker hsc_env ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -126,15 +126,17 @@ data StgArg -- If so, we can't allocate it statically isDllConApp :: DynFlags -> Module -> DataCon -> [StgArg] -> Bool isDllConApp dflags this_mod con args - | platformOS (targetPlatform dflags) == OSMinGW32 - = isDynLinkName dflags this_mod (dataConName con) || any is_dll_arg args + | not (gopt Opt_ExternalDynamicRefs dflags) = False + | platformOS platform == OSMinGW32 + = isDynLinkName platform this_mod (dataConName con) || any is_dll_arg args | otherwise = False where + platform = targetPlatform dflags -- NB: typePrimRep1 is legit because any free variables won't have -- unlifted type (there are no unlifted things at top level) is_dll_arg :: StgArg -> Bool is_dll_arg (StgVarArg v) = isAddrRep (typePrimRep1 (idType v)) - && isDynLinkName dflags this_mod (idName v) + && isDynLinkName platform this_mod (idName v) is_dll_arg _ = False -- True of machine addresses; these are the things that don't work across DLLs. ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -1342,8 +1342,9 @@ gen_data dflags data_type_name constr_names loc rep_tc L loc (TypeSig noExtField [L loc data_type_name] sig_ty)) sig_ty = mkLHsSigWcType (nlHsTyVar dataType_RDR) + ctx = initDefaultSDocContext dflags rhs = nlHsVar mkDataType_RDR - `nlHsApp` nlHsLit (mkHsString (showSDocOneLine dflags (ppr rep_tc))) + `nlHsApp` nlHsLit (mkHsString (showSDocOneLine ctx (ppr rep_tc))) `nlHsApp` nlList (map nlHsVar constr_names) genDataDataCon :: DataCon -> RdrName -> DerivStuff ===================================== compiler/GHC/Tc/Types.hs ===================================== @@ -70,6 +70,7 @@ module GHC.Tc.Types( TcId, TcIdSet, NameShape(..), removeBindingShadowing, + getPlatform, -- Constraint solver plugins TcPlugin(..), TcPluginResult(..), TcPluginSolver, @@ -84,6 +85,7 @@ module GHC.Tc.Types( #include "HsVersions.h" import GhcPrelude +import GHC.Platform import GHC.Hs import GHC.Driver.Types @@ -902,6 +904,11 @@ removeBindingShadowing bindings = reverse $ fst $ foldl else (binding:bindingAcc, extendOccSet seenNames (occName binding))) ([], emptyOccSet) bindings + +-- | Get target platform +getPlatform :: TcM Platform +getPlatform = targetPlatform <$> getDynFlags + --------------------------- -- Template Haskell stages and levels --------------------------- ===================================== compiler/main/ErrUtils.hs ===================================== @@ -729,12 +729,13 @@ withTiming' dflags what force_result prtimings action then do whenPrintTimings $ logInfo dflags (defaultUserStyle dflags) $ text "***" <+> what <> colon - eventBegins dflags what + let ctx = initDefaultSDocContext dflags + eventBegins ctx what alloc0 <- liftIO getAllocationCounter start <- liftIO getCPUTime !r <- action () <- pure $ force_result r - eventEnds dflags what + eventEnds ctx what end <- liftIO getCPUTime alloc1 <- liftIO getAllocationCounter -- recall that allocation counter counts down @@ -753,7 +754,7 @@ withTiming' dflags what force_result prtimings action whenPrintTimings $ dumpIfSet_dyn dflags Opt_D_dump_timings "" FormatText - $ text $ showSDocOneLine dflags + $ text $ showSDocOneLine ctx $ hsep [ what <> colon , text "alloc=" <> ppr alloc , text "time=" <> doublePrec 3 time @@ -762,15 +763,15 @@ withTiming' dflags what force_result prtimings action else action where whenPrintTimings = liftIO . when (prtimings == PrintTimings) - eventBegins dflags w = do - whenPrintTimings $ traceMarkerIO (eventBeginsDoc dflags w) - liftIO $ traceEventIO (eventBeginsDoc dflags w) - eventEnds dflags w = do - whenPrintTimings $ traceMarkerIO (eventEndsDoc dflags w) - liftIO $ traceEventIO (eventEndsDoc dflags w) - - eventBeginsDoc dflags w = showSDocOneLine dflags $ text "GHC:started:" <+> w - eventEndsDoc dflags w = showSDocOneLine dflags $ text "GHC:finished:" <+> w + eventBegins ctx w = do + whenPrintTimings $ traceMarkerIO (eventBeginsDoc ctx w) + liftIO $ traceEventIO (eventBeginsDoc ctx w) + eventEnds ctx w = do + whenPrintTimings $ traceMarkerIO (eventEndsDoc ctx w) + liftIO $ traceEventIO (eventEndsDoc ctx w) + + eventBeginsDoc ctx w = showSDocOneLine ctx $ text "GHC:started:" <+> w + eventEndsDoc ctx w = showSDocOneLine ctx $ text "GHC:finished:" <+> w debugTraceMsg :: DynFlags -> Int -> MsgDoc -> IO () debugTraceMsg dflags val msg = ifVerbose dflags val $ ===================================== compiler/utils/Outputable.hs ===================================== @@ -96,7 +96,7 @@ import GhcPrelude import {-# SOURCE #-} GHC.Driver.Session ( DynFlags, hasPprDebug, hasNoDebugOutput - , pprUserLength, pprCols + , pprUserLength , unsafeGlobalDynFlags, initSDocContext ) import {-# SOURCE #-} GHC.Types.Module( UnitId, Module, ModuleName, moduleName ) @@ -484,43 +484,43 @@ whenPprDebug d = ifPprDebug d empty -- | The analog of 'Pretty.printDoc_' for 'SDoc', which tries to make sure the -- terminal doesn't get screwed up by the ANSI color codes if an exception -- is thrown during pretty-printing. -printSDoc :: Mode -> DynFlags -> Handle -> PprStyle -> SDoc -> IO () -printSDoc mode dflags handle sty doc = +printSDoc :: SDocContext -> Mode -> Handle -> SDoc -> IO () +printSDoc ctx mode handle doc = Pretty.printDoc_ mode cols handle (runSDoc doc ctx) `finally` Pretty.printDoc_ mode cols handle (runSDoc (coloured Col.colReset empty) ctx) where - cols = pprCols dflags - ctx = initSDocContext dflags sty + cols = sdocLineLength ctx -- | Like 'printSDoc' but appends an extra newline. -printSDocLn :: Mode -> DynFlags -> Handle -> PprStyle -> SDoc -> IO () -printSDocLn mode dflags handle sty doc = - printSDoc mode dflags handle sty (doc $$ text "") +printSDocLn :: SDocContext -> Mode -> Handle -> SDoc -> IO () +printSDocLn ctx mode handle doc = + printSDoc ctx mode handle (doc $$ text "") printForUser :: DynFlags -> Handle -> PrintUnqualified -> SDoc -> IO () printForUser dflags handle unqual doc - = printSDocLn PageMode dflags handle - (mkUserStyle dflags unqual AllTheWay) doc + = printSDocLn ctx PageMode handle doc + where ctx = initSDocContext dflags (mkUserStyle dflags unqual AllTheWay) printForUserPartWay :: DynFlags -> Handle -> Int -> PrintUnqualified -> SDoc -> IO () printForUserPartWay dflags handle d unqual doc - = printSDocLn PageMode dflags handle - (mkUserStyle dflags unqual (PartWay d)) doc + = printSDocLn ctx PageMode handle doc + where ctx = initSDocContext dflags (mkUserStyle dflags unqual (PartWay d)) -- | Like 'printSDocLn' but specialized with 'LeftMode' and -- @'PprCode' 'CStyle'@. This is typically used to output C-- code. printForC :: DynFlags -> Handle -> SDoc -> IO () printForC dflags handle doc = - printSDocLn LeftMode dflags handle (PprCode CStyle) doc + printSDocLn ctx LeftMode handle doc + where ctx = initSDocContext dflags (PprCode CStyle) -- | An efficient variant of 'printSDoc' specialized for 'LeftMode' that -- outputs to a 'BufHandle'. -bufLeftRenderSDoc :: DynFlags -> BufHandle -> PprStyle -> SDoc -> IO () -bufLeftRenderSDoc dflags bufHandle sty doc = - Pretty.bufLeftRender bufHandle (runSDoc doc (initSDocContext dflags sty)) +bufLeftRenderSDoc :: SDocContext -> BufHandle -> SDoc -> IO () +bufLeftRenderSDoc ctx bufHandle doc = + Pretty.bufLeftRender bufHandle (runSDoc doc ctx) pprCode :: CodeStyle -> SDoc -> SDoc pprCode cs d = withPprStyle (PprCode cs) d @@ -566,12 +566,12 @@ renderWithStyle ctx sdoc -- This shows an SDoc, but on one line only. It's cheaper than a full -- showSDoc, designed for when we're getting results like "Foo.bar" -- and "foo{uniq strictness}" so we don't want fancy layout anyway. -showSDocOneLine :: DynFlags -> SDoc -> String -showSDocOneLine dflags d +showSDocOneLine :: SDocContext -> SDoc -> String +showSDocOneLine ctx d = let s = Pretty.style{ Pretty.mode = OneLineMode, - Pretty.lineLength = pprCols dflags } in + Pretty.lineLength = sdocLineLength ctx } in Pretty.renderStyle s $ - runSDoc d (initSDocContext dflags (defaultUserStyle dflags)) + runSDoc d ctx showSDocDumpOneLine :: DynFlags -> SDoc -> String showSDocDumpOneLine dflags d ===================================== ghc/GHCi/UI.hs ===================================== @@ -1168,7 +1168,7 @@ enqueueCommands cmds = do -- The return value True indicates success, as in `runOneCommand`. runStmt :: GhciMonad m => String -> SingleStep -> m (Maybe GHC.ExecResult) runStmt input step = do - dflags <- GHC.getInteractiveDynFlags + pflags <- Lexer.mkParserFlags <$> GHC.getInteractiveDynFlags -- In GHCi, we disable `-fdefer-type-errors`, as well as `-fdefer-type-holes` -- and `-fdefer-out-of-scope-variables` for **naked expressions**. The -- declarations and statements are not affected. @@ -1177,7 +1177,7 @@ runStmt input step = do let source = progname st let line = line_number st - if | GHC.isStmt dflags input -> do + if | GHC.isStmt pflags input -> do hsc_env <- GHC.getSession mb_stmt <- liftIO (runInteractiveHsc hsc_env (hscParseStmtWithLocation source line input)) case mb_stmt of @@ -1187,13 +1187,13 @@ runStmt input step = do Just stmt -> run_stmt stmt - | GHC.isImport dflags input -> run_import + | GHC.isImport pflags input -> run_import -- Every import declaration should be handled by `run_import`. As GHCi -- in general only accepts one command at a time, we simply throw an -- exception when the input contains multiple commands of which at least -- one is an import command (see #10663). - | GHC.hasImport dflags input -> throwGhcException + | GHC.hasImport pflags input -> throwGhcException (CmdLineError "error: expecting a single import declaration") -- Otherwise assume a declaration (or a list of declarations) ===================================== libraries/ghc-boot/GHC/Platform.hs ===================================== @@ -2,37 +2,38 @@ -- | A description of the platform we're compiling for. -- -module GHC.Platform ( - PlatformMini(..), - PlatformWordSize(..), - Platform(..), platformArch, platformOS, - Arch(..), - OS(..), - ArmISA(..), - ArmISAExt(..), - ArmABI(..), - PPC_64ABI(..), - ByteOrder(..), - - target32Bit, - isARM, - osElfTarget, - osMachOTarget, - osSubsectionsViaSymbols, - platformUsesFrameworks, - platformWordSizeInBytes, - platformWordSizeInBits, - platformMinInt, - platformMaxInt, - platformMaxWord, - platformInIntRange, - platformInWordRange, - - PlatformMisc(..), - IntegerLibrary(..), - - stringEncodeArch, - stringEncodeOS, +module GHC.Platform + ( PlatformMini(..) + , PlatformWordSize(..) + , Platform(..) + , platformArch + , platformOS + , Arch(..) + , OS(..) + , ArmISA(..) + , ArmISAExt(..) + , ArmABI(..) + , PPC_64ABI(..) + , ByteOrder(..) + , target32Bit + , isARM + , osElfTarget + , osMachOTarget + , osSubsectionsViaSymbols + , platformUsesFrameworks + , platformWordSizeInBytes + , platformWordSizeInBits + , platformMinInt + , platformMaxInt + , platformMaxWord + , platformInIntRange + , platformInWordRange + , PlatformMisc(..) + , IntegerLibrary(..) + , stringEncodeArch + , stringEncodeOS + , SseVersion (..) + , BmiVersion (..) ) where @@ -338,3 +339,24 @@ platformInIntRange platform x = x >= platformMinInt platform && x <= platformMax -- | Test if the given Integer is representable with a platform Word platformInWordRange :: Platform -> Integer -> Bool platformInWordRange platform x = x >= 0 && x <= platformMaxWord platform + + +-------------------------------------------------- +-- Instruction sets +-------------------------------------------------- + +-- | x86 SSE instructions +data SseVersion + = SSE1 + | SSE2 + | SSE3 + | SSE4 + | SSE42 + deriving (Eq, Ord) + +-- | x86 BMI (bit manipulation) instructions +data BmiVersion + = BMI1 + | BMI2 + deriving (Eq, Ord) + ===================================== testsuite/tests/ghc-api/T9015.hs ===================================== @@ -2,8 +2,9 @@ module Main where import GHC import GHC.Driver.Session -import System.Environment import GHC.Driver.Monad +import GHC.Parser.Lexer (mkParserFlags) +import System.Environment testStrings = [ "import Data.Maybe" @@ -52,7 +53,8 @@ main = do where testWithParser parser = do dflags <- getSessionDynFlags - liftIO . putStrLn . unlines $ map (testExpr (parser dflags)) testStrings + let pflags = mkParserFlags dflags + liftIO . putStrLn . unlines $ map (testExpr (parser pflags)) testStrings testExpr parser expr = do expr ++ ": " ++ show (parser expr) ===================================== testsuite/tests/regalloc/regalloc_unit_tests.hs ===================================== @@ -26,6 +26,8 @@ import qualified GHC.CmmToAsm.X86.Instr as X86.Instr import GHC.Driver.Main import GHC.StgToCmm.CgUtils import GHC.CmmToAsm +import GHC.CmmToAsm.Config +import GHC.CmmToAsm.Monad as NCGConfig import GHC.Cmm.Info.Build import GHC.Cmm.Pipeline import GHC.Cmm.Parser @@ -97,13 +99,13 @@ assertIO = assertOr $ \msg -> void (throwIO . RegAllocTestException $ msg) compileCmmForRegAllocStats :: DynFlags -> FilePath -> - (DynFlags -> + (NCGConfig -> NcgImpl (Alignment, RawCmmStatics) X86.Instr.Instr X86.Instr.JumpDest) -> UniqSupply -> IO [( Maybe [Color.RegAllocStats (Alignment, RawCmmStatics) X86.Instr.Instr] , Maybe [Linear.RegAllocStats])] compileCmmForRegAllocStats dflags' cmmFile ncgImplF us = do - let ncgImpl = ncgImplF dflags + let ncgImpl = ncgImplF (NCGConfig.initConfig dflags) hscEnv <- newHscEnv dflags -- parse the cmm file and output any warnings or errors View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bca02fca0119354a6201fd5d019a553015ba2dd8...747093b7c23a1cf92b564eb3d9efe2adc15330df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bca02fca0119354a6201fd5d019a553015ba2dd8...747093b7c23a1cf92b564eb3d9efe2adc15330df You're receiving 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 21 13:38:32 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 21 Apr 2020 09:38:32 -0400 Subject: [Git][ghc/ghc][wip/T17173] 11 commits: Derive Ord instance for Extension Message-ID: <5e9ef758c99a9_6167e4e49b4617863d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17173 at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - 11e69aaa by Simon Peyton Jones at 2020-04-21T14:38:26+01:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Heap/Inspect.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12ae4eda5ec2ac968a56cf97972bb75623536bce...11e69aaa8b55322b1aa9edba8c2ea17441b9f3c3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12ae4eda5ec2ac968a56cf97972bb75623536bce...11e69aaa8b55322b1aa9edba8c2ea17441b9f3c3 You're receiving 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 21 15:59:58 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 21 Apr 2020 11:59:58 -0400 Subject: [Git][ghc/ghc][wip/runRW] Don't look through casts in CoreLint Message-ID: <5e9f187e20629_61673f81afeb5fbc622523b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: c1f35320 by Ben Gamari at 2020-04-21T15:59:13+00:00 Don't look through casts in CoreLint - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -710,9 +710,6 @@ lintJoinLams join_arity enforce rhs where go 0 rhs = lintCoreExpr rhs go n (Lam var expr) = lintLambda var $ go (n-1) expr - go n (Cast expr co) = do { _ <- go n expr - ; lintCastExpr expr co - } -- N.B. join points can be cast. e.g. we consider ((\x -> ...) `cast` ...) -- to be a join point at join arity 1. go n _other | Just bndr <- enforce -- Join point with too few RHS lambdas View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c1f35320a1ee3885ff8291cac9dfeefb6b32fb06 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c1f35320a1ee3885ff8291cac9dfeefb6b32fb06 You're receiving 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 21 16:41:31 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 21 Apr 2020 12:41:31 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Consider unboxing effects of WW better and get rid of hack Message-ID: <5e9f223bd0b6e_6167f52659862291c1@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 063b38a6 by Sebastian Graf at 2020-04-21T18:41:23+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - 3 changed files: - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Op/CprAnal.hs - compiler/GHC/Types/Cpr.hs Changes: ===================================== compiler/GHC/Core/Arity.hs ===================================== @@ -12,7 +12,7 @@ -- | Arity and eta expansion module GHC.Core.Arity - ( manifestArity, joinRhsArity, exprArity, typeArity + ( manifestArity, joinRhsArity, exprArity, typeArity, splitFunNewTys , exprEtaExpandArity, findRhsArity, etaExpand , etaExpandToJoinPoint, etaExpandToJoinPointRule , exprBotStrictness_maybe @@ -41,6 +41,7 @@ import GHC.Driver.Session ( DynFlags, GeneralFlag(..), gopt ) import Outputable import FastString import Util ( debugIsOn ) +import Maybes {- ************************************************************************ @@ -117,33 +118,37 @@ typeArity :: Type -> [OneShotInfo] -- How many value arrows are visible in the type? -- We look through foralls, and newtypes -- See Note [exprArity invariant] -typeArity ty - = go initRecTc ty +typeArity ty = mapMaybe go (fst (splitPiNewTys ty)) where - go rec_nts ty - | Just (_, ty') <- splitForAllTy_maybe ty - = go rec_nts ty' - - | Just (arg,res) <- splitFunTy_maybe ty - = typeOneShot arg : go rec_nts res + -- Important to look through non-recursive newtypes, so that, eg + -- (f x) where f has arity 2, f :: Int -> IO () + -- Here we want to get arity 1 for the result! + -- + -- AND through a layer of recursive newtypes + -- e.g. newtype Stream m a b = Stream (m (Either b (a, Stream m a b))) + go ty_co_bndr = typeOneShot <$> binderRelevantType_maybe ty_co_bndr + +-- | Like 'splitFunTys', but this one also looks through newtypes and foralls. +splitFunNewTys :: Type -> ([Type], Type) +splitFunNewTys ty = (mapMaybe binderRelevantType_maybe arg_bndrs, res_ty) + where + (arg_bndrs, res_ty) = splitPiNewTys ty +-- | Like 'splitPiTys', but this one also looks through newtypes. +splitPiNewTys :: Type -> ([TyCoBinder], Type) +splitPiNewTys ty = go initRecTc ty [] + where + go rec_nts ty arg_tys + -- ForAllTys and FunTys + | Just (arg, res_ty) <- splitPiTy_maybe ty + = go rec_nts res_ty (arg:arg_tys) + -- See Note [Expanding newtypes] in GHC.Core.TyCon | Just (tc,tys) <- splitTyConApp_maybe ty , Just (ty', _) <- instNewTyCon_maybe tc tys - , Just rec_nts' <- checkRecTc rec_nts tc -- See Note [Expanding newtypes] - -- in GHC.Core.TyCon --- , not (isClassTyCon tc) -- Do not eta-expand through newtype classes --- -- See Note [Newtype classes and eta expansion] --- (no longer required) - = go rec_nts' ty' - -- Important to look through non-recursive newtypes, so that, eg - -- (f x) where f has arity 2, f :: Int -> IO () - -- Here we want to get arity 1 for the result! - -- - -- AND through a layer of recursive newtypes - -- e.g. newtype Stream m a b = Stream (m (Either b (a, Stream m a b))) - + , Just rec_nts' <- checkRecTc rec_nts tc + = go rec_nts' ty' arg_tys | otherwise - = [] + = (reverse arg_tys, ty) --------------- exprBotStrictness_maybe :: CoreExpr -> Maybe (Arity, StrictSig) ===================================== compiler/GHC/Core/Op/CprAnal.hs ===================================== @@ -17,6 +17,7 @@ import GHC.Driver.Session import GHC.Types.Demand import GHC.Types.Cpr import GHC.Core +import GHC.Core.Arity ( splitFunNewTys ) import GHC.Core.Seq import Outputable import GHC.Types.Var.Env @@ -206,7 +207,7 @@ cprAnal' env args (Case scrut case_bndr ty alts) (whnf_flag, case_bndr_ty) = forceCprTy (getStrDmd seqDmd) scrut_ty -- Regardless of whether scrut had the CPR property or not, the case binder -- certainly has it. See 'extendEnvForDataAlt'. - (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args scrut case_bndr case_bndr_ty) alts + (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args case_bndr case_bndr_ty) alts res_ty = foldl' lubCprType botCprType alt_tys `bothCprType` whnf_flag cprAnal' env args (Let (NonRec id rhs) body) @@ -225,18 +226,17 @@ cprAnal' env args (Let (Rec pairs) body) cprAnalAlt :: AnalEnv -> [CprType] -- ^ info about incoming arguments - -> CoreExpr -- ^ scrutinee -> Id -- ^ case binder -> CprType -- ^ info about the case binder -> Alt Var -- ^ current alternative -> (CprType, Alt Var) -cprAnalAlt env args scrut case_bndr case_bndr_ty (con@(DataAlt dc),bndrs,rhs) +cprAnalAlt env args case_bndr case_bndr_ty (con@(DataAlt dc),bndrs,rhs) -- See 'extendEnvForDataAlt' and Note [CPR in a DataAlt case alternative] = (rhs_ty, (con, bndrs, rhs')) where - env_alt = extendEnvForDataAlt env scrut case_bndr case_bndr_ty dc bndrs + env_alt = extendEnvForDataAlt env case_bndr case_bndr_ty dc bndrs (rhs_ty, rhs') = cprAnal env_alt args rhs -cprAnalAlt env args _ case_bndr case_bndr_ty (con,bndrs,rhs) +cprAnalAlt env args case_bndr case_bndr_ty (con,bndrs,rhs) = (rhs_ty, (con, bndrs, rhs')) where env' = extendAnalEnv env case_bndr (CprSig case_bndr_ty) @@ -330,6 +330,18 @@ pruneSig d (CprSig cpr_ty) -- behavior. = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty `lubCpr` initRecFunCpr) } +unboxingStrategy :: AnalEnv -> UnboxingStrategy +unboxingStrategy env ty dmd + = prj <$> wantToUnbox (ae_fam_envs env) has_inlineable_prag ty dmd + where + prj (dmds, DataConAppContext { dcac_dc = dc, dcac_arg_tys = tys_w_str }) + = (dc, map fst tys_w_str, dmds) + -- Rather than maintaining in AnalEnv whether we are in an INLINEABLE + -- function, we just assume that we aren't. That flag is only relevant + -- to Note [Do not unpack class dictionaries], the few unboxing + -- opportunities on dicts it prohibits are probably irrelevant to CPR. + has_inlineable_prag = False + -- | Process the RHS of the binding for a sensible arity, add the CPR signature -- to the Id, and augment the environment with the signature as well. cprAnalBind @@ -342,20 +354,23 @@ cprAnalBind cprAnalBind top_lvl env args id rhs = (id', rhs') where + arg_tys = fst (splitFunNewTys (idType id)) -- We compute the Termination and CPR transformer based on the strictness -- signature. There is no point in pretending that an arg we are strict in -- could lead to non-termination, as the signature then trivially -- MightDiverge. Instead we assume that call sites make sure to force the -- arguments appropriately and unleash the TerminationFlag there. - assumed_arg_tys = argCprTypesFromStrictSig (idStrictness id) + assumed_arg_cpr_tys = argCprTypesFromStrictSig (unboxingStrategy env) + arg_tys + (idStrictness id) -- TODO: Not sure if that special handling of join points is really -- necessary. It might even be harmful if the excess 'args' aren't unboxed -- and we blindly assume that they have the CPR property! So we should -- try out getting rid of this special case and 'args'. (rhs_ty, rhs') - | isJoinId id = cprAnal env (assumed_arg_tys ++ args) rhs - | otherwise = cprAnal env assumed_arg_tys rhs + | isJoinId id = cprAnal env (assumed_arg_cpr_tys ++ args) rhs + | otherwise = cprAnal env assumed_arg_cpr_tys rhs -- possibly trim thunk CPR info rhs_ty' @@ -438,86 +453,48 @@ emptyAnalEnv fam_envs , ae_fam_envs = fam_envs } --- | Extend an environment with the strictness IDs attached to the id +extendAnalEnv :: AnalEnv -> Id -> CprSig -> AnalEnv +extendAnalEnv env id sig + = env { ae_sigs = extendVarEnv (ae_sigs env) id sig } + +extendAnalEnvList :: AnalEnv -> [(Id, CprSig)] -> AnalEnv +extendAnalEnvList env ids_cprs + = env { ae_sigs = extendVarEnvList (ae_sigs env) ids_cprs } + +-- | Extend an environment with the CPR signatures attached to the id extendAnalEnvs :: AnalEnv -> [Id] -> AnalEnv extendAnalEnvs env ids = env { ae_sigs = sigs' } where sigs' = extendVarEnvList (ae_sigs env) [ (id, idCprInfo id) | id <- ids ] -extendAnalEnv :: AnalEnv -> Id -> CprSig -> AnalEnv -extendAnalEnv env id sig - = env { ae_sigs = extendVarEnv (ae_sigs env) id sig } - lookupSigEnv :: AnalEnv -> Id -> Maybe CprSig lookupSigEnv env id = lookupVarEnv (ae_sigs env) id nonVirgin :: AnalEnv -> AnalEnv nonVirgin env = env { ae_virgin = False } -dummyArgs :: DataCon -> [CprType] -dummyArgs dc = take (dataConRepArity dc) (repeat topCprType) - --- | A version of 'extendAnalEnv' for a binder of which we don't see the RHS --- needed to compute a 'CprSig' (e.g. lambdas and DataAlt field binders). --- In this case, we can still look at their demand to attach CPR signatures --- anticipating the unboxing done by worker/wrapper. --- See Note [CPR for binders that will be unboxed]. -extendAnalEnvForDemand :: AnalEnv -> Id -> Demand -> CprType -> AnalEnv -extendAnalEnvForDemand env id dmd ty - | isId id - , Just (_, DataConAppContext { dcac_dc = dc }) - <- wantToUnbox (ae_fam_envs env) has_inlineable_prag (idType id) dmd - -- TODO: Make this deep, depending on the StrDmd - = extendAnalEnv env id $ CprSig $ - markConCprType Terminates (dataConTag dc) (dummyArgs dc) $ - -- TODO: There has to be a better way of forcing - snd $ forceCprTy (getStrDmd dmd) ty - | otherwise - = env - where - -- Rather than maintaining in AnalEnv whether we are in an INLINEABLE - -- function, we just assume that we aren't. That flag is only relevant - -- to Note [Do not unpack class dictionaries], the few unboxing - -- opportunities on dicts it prohibits are probably irrelevant to CPR. - has_inlineable_prag = False - -extendEnvForDataAlt :: AnalEnv -> CoreExpr -> Id -> CprType -> DataCon -> [Var] -> AnalEnv +extendEnvForDataAlt :: AnalEnv -> Id -> CprType -> DataCon -> [Var] -> AnalEnv -- See Note [CPR in a DataAlt case alternative] -extendEnvForDataAlt env scrut case_bndr case_bndr_ty dc bndrs - = foldl' do_con_arg env' ids_w_strs +extendEnvForDataAlt env case_bndr case_bndr_ty dc bndrs + = extendAnalEnv env' case_bndr (CprSig case_bndr_ty') where - env' = extendAnalEnv env case_bndr (CprSig case_bndr_sig) - - ids_w_strs = filter isId bndrs `zip` dataConRepStrictness dc - tycon = dataConTyCon dc is_product = isJust (isDataProductTyCon_maybe tycon) is_sum = isJust (isDataSumTyCon_maybe tycon) - case_bndr_sig - | is_product || is_sum = undefined -- markConCprType (dataConTag dc) (dummyArgs dc) case_bndr_ty + case_bndr_ty' + | is_product || is_sum = markConCprType dc case_bndr_ty -- Any of the constructors had existentials. This is a little too -- conservative (after all, we only care about the particular data con), -- but there is no easy way to write is_sum and this won't happen much. - | otherwise = case_bndr_ty - - -- We could have much deeper CPR info here with Nested CPR, which could - -- propagate available unboxed things from the scrutinee, getting rid of - -- the is_var_scrut heuristic. See Note [CPR in a DataAlt case alternative]. - -- Giving strict binders the CPR property only makes sense for products, as - -- the arguments in Note [CPR for binders that will be unboxed] don't apply - -- to sums (yet); we lack WW for strict binders of sum type. - do_con_arg env (id, str) - | is_var scrut - -- See Note [Add demands for strict constructors] in WorkWrap.Lib - , let dmd = applyWhen (isMarkedStrict str) strictifyDmd (idDemandInfo id) - = extendAnalEnvForDemand env id dmd topCprType - | otherwise - = env - - is_var (Cast e _) = is_var e - is_var (Var v) = isLocalId v - is_var _ = False + | otherwise = case_bndr_ty + env' + | Just fields <- splitConCprTy dc case_bndr_ty' + , let ids = filter isId bndrs + , let cpr_tys = map (CprSig . CprType 0) fields + = extendAnalEnvList env (zipEqual "extendEnvForDataAlt" ids cpr_tys) + | otherwise + = env {- Note [Ensuring termination of fixed-point iteration] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -10,11 +10,11 @@ module GHC.Types.Cpr ( TerminationFlag (Terminates), Cpr, topCpr, botCpr, conCpr, initRecFunCpr, lubCpr, asConCpr, - CprType (..), topCprType, botCprType, conCprType, pruneDeepCpr, - markConCprType, lubCprType, applyCprTy, abstractCprTy, abstractCprTyNTimes, - ensureCprTyArity, trimCprTy, + CprType (..), topCprType, botCprType, lubCprType, conCprType, + pruneDeepCpr, markConCprType, splitConCprTy, applyCprTy, abstractCprTy, + abstractCprTyNTimes, ensureCprTyArity, trimCprTy, forceCprTy, forceCpr, bothCprType, - cprTransformDataConSig, cprTransformSig, argCprTypesFromStrictSig, + cprTransformDataConSig, UnboxingStrategy, cprTransformSig, argCprTypesFromStrictSig, CprSig (..), mkCprSig, mkCprSigForArity, topCprSig, seqCprSig ) where @@ -26,6 +26,7 @@ import GhcPrelude import GHC.Types.Basic import GHC.Types.Demand import GHC.Core.DataCon +import GHC.Core.Type import Outputable import Binary import Util @@ -179,7 +180,7 @@ initRecFunCpr :: Cpr initRecFunCpr = Cpr MightDiverge Bot conCpr :: TerminationFlag -> ConTag -> [Cpr] -> Cpr -conCpr tm t fs = Cpr tm (Levitate (Con t fs)) +conCpr tf t fs = Cpr tf (Levitate (Con t fs)) -- | Forget encoded CPR info, but keep termination info. forgetCpr :: Cpr -> Termination @@ -244,6 +245,18 @@ topCprType = CprType 0 topCpr botCprType :: CprType botCprType = CprType 0 botCpr +lubCprType :: CprType -> CprType -> CprType +lubCprType ty1@(CprType n1 cpr1) ty2@(CprType n2 cpr2) + | ct_cpr ty1 == botCpr && n1 <= n2 = ty2 + | ct_cpr ty2 == botCpr && n2 <= n1 = ty1 + -- There might be non-bottom CPR types with mismatching arities. + -- Consider test DmdAnalGADTs. We want to return topCpr in these cases. + -- Returning topCprType is a safe default. + | n1 == n2 + = CprType n1 (lubCpr cpr1 cpr2) + | otherwise + = topCprType + extractArgCprAndTermination :: [CprType] -> [Cpr] extractArgCprAndTermination = map go where @@ -256,22 +269,30 @@ conCprType con_tag args = CprType 0 (conCpr Terminates con_tag cprs) where cprs = extractArgCprAndTermination args -markConCprType :: TerminationFlag -> ConTag -> [CprType] -> CprType -> CprType -markConCprType tf con_tag args ty = ASSERT( ct_arty ty == 0 ) ty { ct_cpr = conCpr tf con_tag cprs } +markConCprType :: DataCon -> CprType -> CprType +markConCprType dc _ty@(CprType n cpr) + = ASSERT2( n == 0, ppr _ty ) CprType 0 (conCpr Terminates con_tag fields) where - cprs = extractArgCprAndTermination args - -lubCprType :: CprType -> CprType -> CprType -lubCprType ty1@(CprType n1 cpr1) ty2@(CprType n2 cpr2) - | ct_cpr ty1 == botCpr && n1 <= n2 = ty2 - | ct_cpr ty2 == botCpr && n2 <= n1 = ty1 - -- There might be non-bottom CPR types with mismatching arities. - -- Consider test DmdAnalGADTs. We want to return topCpr in these cases. - -- Returning topCprType is a safe default. - | n1 == n2 - = CprType n1 (lubCpr cpr1 cpr2) - | otherwise - = topCprType + con_tag = dataConTag dc + wkr_arity = dataConRepArity dc + fields = case cpr of + NoMoreCpr (Term _ (Levitate (Con t terms))) + | con_tag == t -> map NoMoreCpr terms + NoMoreCpr (Term _ Bot) -> replicate wkr_arity (NoMoreCpr botTerm) + Cpr _ (Levitate (Con t cprs)) + | con_tag == t -> cprs + Cpr _ Bot -> replicate wkr_arity botCpr + _ -> replicate wkr_arity topCpr + +splitConCprTy :: DataCon -> CprType -> Maybe [Cpr] +splitConCprTy dc (CprType 0 (Cpr _ l)) + | Bot <- l + = Just (replicate (dataConRepArity dc) botCpr) + | Levitate (Con t fields) <- l + , dataConTag dc == t + = Just fields +splitConCprTy _ _ + = Nothing applyCprTy :: CprType -> CprType applyCprTy (CprType n cpr) @@ -392,18 +413,15 @@ forceCpr str cpr = runTerminationM (forceCprM str cpr) -- | 'lubTerm's the given outer @TerminationFlag@ on the @CprType at s 'ct_term'. bothCprType :: CprType -> TerminationFlag -> CprType --- deepTerm because we only want to affect the WHNF layer. --- If tm = Terminates, it's just 'id'. --- If tm = MightDiverge, it will only set the WHNF layer to MightDiverge, +-- If tf = Terminates, it's just 'id'. +-- If tf = MightDiverge, it will only set the WHNF layer to MightDiverge, -- leaving nested termination info (e.g. on product components) intact. -bothCprType ct tf = ct { ct_cpr = bothCpr (ct_cpr ct) tf } - -bothCpr :: Cpr -> TerminationFlag -> Cpr -bothCpr (NoMoreCpr t) tf = NoMoreCpr (bothTerm t tf) -bothCpr (Cpr tf1 l_sh) tf2 = Cpr (lubTermFlag tf1 tf2) l_sh +bothCprType ct Terminates = ct +bothCprType ct MightDiverge = ct { ct_cpr = shallowDivCpr (ct_cpr ct) } -bothTerm :: Termination -> TerminationFlag -> Termination -bothTerm (Term tf1 l_sh) tf2 = Term (lubTermFlag tf1 tf2) l_sh +shallowDivCpr :: Cpr -> Cpr +shallowDivCpr (NoMoreCpr (Term _ l_sh)) = NoMoreCpr (Term MightDiverge l_sh) +shallowDivCpr (Cpr _ l_sh) = Cpr MightDiverge l_sh seqCprType :: CprType -> () seqCprType (CprType _ cpr) = seqCpr cpr @@ -461,20 +479,24 @@ cprTransformDataConSig con args cprTransformSig :: StrictSig -> CprSig -> [CprType] -> CprType cprTransformSig str_sig (CprSig sig_ty) arg_tys - | arg_strs <- argStrsFromStrictSig str_sig - , arg_tys `equalLength` arg_strs - , ASSERT( length arg_tys == ct_arty sig_ty ) True - , (tf, _) <- runTerminationM $ zipWithM_ forceCprTyM arg_strs arg_tys + | arg_strs <- map getStrDmd $ argDmdsFromStrictSig str_sig + , arg_strs `leLength` arg_tys + , arg_tys `lengthIs` ct_arty sig_ty + -- Maybe we should use resTypeArgDmd instead of strTop here. On the other + -- hand, I don't think it makes much of a difference; We basically only need + -- to pad with strTop when str_sig was topSig to begin with. + , (tf, _) <- runTerminationM $ zipWithM_ forceCprTyM (arg_strs ++ repeat strTop) arg_tys = sig_ty `bothCprType` tf - -- TODO: Think about what happens if arg_tys is longer than arg_strs. | otherwise = topCprType -- | We have to be sure that 'cprTransformSig' and 'argCprTypesFromStrictSig' --- agree in how they compute the 'ArgStr's for which the 'CprSig' is computed. --- This function encodes the common logic. -argStrsFromStrictSig :: StrictSig -> [ArgStr] -argStrsFromStrictSig = map getStrDmd . fst . splitStrictSig +-- agree in how they compute the 'Demand's for which the 'CprSig' is computed. +-- This function encodes the common (trivial) logic. +argDmdsFromStrictSig :: StrictSig -> [Demand] +argDmdsFromStrictSig = fst . splitStrictSig + +type UnboxingStrategy = Type -> Demand -> Maybe (DataCon, [Type], [Demand]) -- | Produces 'CprType's the termination info of which match the given -- strictness signature. Examples: @@ -482,11 +504,15 @@ argStrsFromStrictSig = map getStrDmd . fst . splitStrictSig -- - A head-strict demand @S@ would translate to @#@, a -- - A tuple demand @S(S,L)@ would translate to @#(#,*)@ -- - A call demand @C(S)@ would translate to @strTop -> #(#,*)@ -argCprTypesFromStrictSig :: StrictSig -> [CprType] -argCprTypesFromStrictSig sig = arg_tys +argCprTypesFromStrictSig :: UnboxingStrategy -> [Type] -> StrictSig -> [CprType] +argCprTypesFromStrictSig want_to_unbox arg_tys sig + = zipWith go arg_tys (argDmdsFromStrictSig sig) where - arg_strs = argStrsFromStrictSig sig - arg_tys = zipWith ((snd .) . forceCprTy) arg_strs (repeat topCprType) + go arg_ty arg_dmd + | Just (dc, arg_tys, arg_dmds) <- want_to_unbox arg_ty arg_dmd + = conCprType (dataConTag dc) (zipWith go arg_tys arg_dmds) + | otherwise + = snd $ forceCprTy (getStrDmd arg_dmd) topCprType --------------- -- * Outputable @@ -547,8 +573,8 @@ instance Binary r => Binary (KnownShape r) where get bh = Con <$> get bh <*> get bh instance Binary TerminationFlag where - put_ bh MightDiverge = put_ bh False put_ bh Terminates = put_ bh True + put_ bh MightDiverge = put_ bh False get bh = do b <- get bh if b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/063b38a6a8575219f0a4d7e8d5eab2a58060b01d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/063b38a6a8575219f0a4d7e8d5eab2a58060b01d You're receiving 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 21 16:56:34 2020 From: gitlab at gitlab.haskell.org (Peter Trommler) Date: Tue, 21 Apr 2020 12:56:34 -0400 Subject: [Git][ghc/ghc][wip/T11261] 49 commits: testsuite: Fix comment for a language extension Message-ID: <5e9f25c2dccba_61673f81ba8fd524623593e@gitlab.haskell.org.mail> Peter Trommler pushed to branch wip/T11261 at Glasgow Haskell Compiler / GHC Commits: 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - a879d014 by Peter Trommler at 2020-04-21T18:20:03+02:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/374a2ff8cb2abf076b8eae3ceac96cf4a55f48ac...a879d014cbae6c0799c5fb5457963b65b99a81fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/374a2ff8cb2abf076b8eae3ceac96cf4a55f48ac...a879d014cbae6c0799c5fb5457963b65b99a81fe You're receiving 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 21 20:49:05 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 21 Apr 2020 16:49:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18073 Message-ID: <5e9f5c414940e_6167134ebbc462636a6@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18073 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18073 You're receiving 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 21 20:58:57 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Tue, 21 Apr 2020 16:58:57 -0400 Subject: [Git][ghc/ghc][wip/semigroup-sdoc] 43 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5e9f5e9137928_6167134ebbc462666e5@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/semigroup-sdoc at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - 0fa28376 by Vladislav Zavialov at 2020-04-21T23:57:54+03:00 Use Semigroup's (<>) for Doc/SDoc Before this patch, Outputable.hs defined its own (<>) which caused conflicts with (Data.Semigroup.<>) and thus led to inconvenience. However, replacing it is not trivial due to a different fixity: http://www.haskell.org/pipermail/libraries/2011-November/017066.html Nevertheless, it is possible to update the pretty-printing code to work with (<>) of a different fixitiy, and that's what this patch implements. Now Doc and SDoc are instances of Semigroup. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4cf1c5db6135dec71929358f9012d385a7441c1...0fa283769d3427b946dbe7567d24735388897ee1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4cf1c5db6135dec71929358f9012d385a7441c1...0fa283769d3427b946dbe7567d24735388897ee1 You're receiving 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 21 22:49:59 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Tue, 21 Apr 2020 18:49:59 -0400 Subject: [Git][ghc/ghc][wip/haddock-accum] Address a few comments (more tomorrow) Message-ID: <5e9f7897b7560_6167865d29c6296539@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/haddock-accum at Glasgow Haskell Compiler / GHC Commits: b204b5b4 by Vladislav Zavialov at 2020-04-22T01:49:37+03:00 Address a few comments (more tomorrow) - - - - - 3 changed files: - compiler/GHC/Types/SrcLoc.hs - compiler/parser/HaddockUtils.hs - compiler/utils/Util.hs Changes: ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -88,7 +88,8 @@ module GHC.Types.SrcLoc ( mapLoc, -- ** Combining and comparing Located values - eqLocated, cmpLocated, combineLocs, addCLoc, + eqLocated, cmpLocated, cmpBufSpan, + combineLocs, addCLoc, leftmost_smallest, leftmost_largest, rightmost_smallest, spans, isSubspanOf, isRealSubspanOf, sortLocated, sortRealLocated, @@ -726,6 +727,17 @@ eqLocated a b = unLoc a == unLoc b cmpLocated :: Ord a => GenLocated l a -> GenLocated l a -> Ordering cmpLocated a b = unLoc a `compare` unLoc b +-- | Compare the 'BufSpan' of two located things. +-- +-- Precondition: both operands have an associated 'BufSpan'. +cmpBufSpan :: HasDebugCallStack => Located a -> Located a -> Ordering +cmpBufSpan (L l1 _) (L l2 _) + | Just a <- getBufSpan l1 + , Just b <- getBufSpan l2 + = compare a b + + | otherwise = panic "cmpBufSpan: no BufSpan" + instance (Outputable l, Outputable e) => Outputable (GenLocated l e) where ppr (L l e) = -- TODO: We can't do this since Located was refactored into -- GenLocated: ===================================== compiler/parser/HaddockUtils.hs ===================================== @@ -211,6 +211,25 @@ mkHdkM = coerce unHdkM = coerce -- See Note [Adding Haddock comments to the syntax tree]. +-- +-- 'HdkA' provides a way to propagate location information from surrounding +-- computations: +-- +-- left_neighbour <*> HdkA inner_span inner_m <*> right_neighbour +-- +-- Here, the following holds: +-- +-- * the 'left_neighbour' will only see Haddock comments until 'bufSpanStart' of 'inner_span' +-- * the 'right_neighbour' will only see Haddock comments after 'bufSpanEnd' of 'inner_span' +-- * the 'inner_m' will only see Haddock comments between its 'left_neighbour' and its 'right_neighbour' +-- +-- In other words, every computation: +-- +-- * delimits the surrounding computations +-- * is delimited by the surrounding computation +-- +-- Therefore, a 'HdkA' computation must be always considered in the context in +-- which it is used. data HdkA a = HdkA (Maybe BufSpan) (HdkM a) deriving (Functor) @@ -219,19 +238,28 @@ instance Applicative HdkA where HdkA l1 m1 <*> HdkA l2 m2 = HdkA (l1 <> l2) (delim1 m1 <*> delim2 m2) where + -- Delimit the LHS by the location information from the RHS delim1 = inLocRange (locRangeTo (fmap @Maybe bufSpanStart l2)) + -- Delimit the RHS by the location information from the LHS delim2 = inLocRange (locRangeFrom (fmap @Maybe bufSpanEnd l1)) runHdkA :: HdkA a -> [PsLocated HdkComment] -> (a, [PsLocated HdkComment]) runHdkA (HdkA _ m) = unHdkM m mempty --- | Let the neighbours know about an item at this location. +-- Let the neighbours know about an item at this location. -- See Note [Adding Haddock comments to the syntax tree]. registerHdkA :: Located a -> HdkA () registerHdkA a = HdkA (getBufSpan (getLoc a)) (pure ()) -delimitHdkA :: SrcSpan -> HdkA a -> HdkA a -delimitHdkA l' (HdkA l m) = HdkA (getBufSpan l' <> l) m +-- Extend the declared location span of a 'HdkA' computation: +-- +-- left_neighbour <*> extendHdkA l x <*> right_neighbour +-- +-- The declared location of 'x' now includes 'l', so that the surrounding +-- computations 'left_neighbour' and 'right_neighbour' will not look for +-- Haddock comments inside the 'l' location span. +extendHdkA :: SrcSpan -> HdkA a -> HdkA a +extendHdkA l' (HdkA l m) = HdkA (getBufSpan l' <> l) m concatLHsDocString :: [LHsDocString] -> Maybe LHsDocString concatLHsDocString xs = L l <$> concatDocs docs @@ -266,9 +294,9 @@ instance HasHaddock (Located HsModule) where instance HasHaddock (Located [LIE GhcPs]) where addHaddock (L l_exports exports) = - delimitHdkA l_exports $ do + extendHdkA l_exports $ do exports' <- addHaddockInterleaveItems NoLayoutInfo mkDocIE exports - registerHdkA (L (srcLocSpan (srcSpanEnd l_exports)) ()) -- Do not conume comments after the closing parenthesis + registerHdkA (L (srcLocSpan (srcSpanEnd l_exports)) ()) -- Do not consume comments after the closing parenthesis pure $ L l_exports exports' instance HasHaddock (LIE GhcPs) where @@ -363,6 +391,26 @@ mkDocDecl layout_info (L l_comment hdk_comment) HdkCommentNamed s doc -> DocCommentNamed s doc HdkCommentSection n doc -> DocGroup n doc where + -- 'indent_mismatch' checks if the documentation comment has the exact + -- indentation level expected by the parent node. + -- + -- For example, when extracting documentation comments between class + -- method declarations, there are three cases to consider: + -- + -- 1. Indent matches (indent_mismatch=False): + -- class C a where + -- f :: a -> a + -- -- ^ doc on f + -- + -- 2. Indented too much (indent_mismatch=True): + -- class C a where + -- f :: a -> a + -- -- ^ indent mismatch + -- + -- 3. Indented too little (indent_mismatch=True): + -- class C a where + -- f :: a -> a + -- -- ^ indent mismatch indent_mismatch = case layout_info of NoLayoutInfo -> False ExplicitBraces -> False @@ -387,7 +435,7 @@ mkDocPrev _ = Nothing instance HasHaddock (LHsDecl GhcPs) where addHaddock ldecl = - delimitHdkA (getLoc ldecl) $ + extendHdkA (getLoc ldecl) $ for @Located ldecl addHaddock instance HasHaddock (HsDecl GhcPs) where @@ -504,18 +552,18 @@ instance HasHaddock (HsDecl GhcPs) where instance HasHaddock (HsDeriving GhcPs) where addHaddock lderivs = - delimitHdkA (getLoc lderivs) $ + extendHdkA (getLoc lderivs) $ for @Located lderivs addHaddock instance HasHaddock (LHsDerivingClause GhcPs) where addHaddock lderiv = - delimitHdkA (getLoc lderiv) $ + extendHdkA (getLoc lderiv) $ for @Located lderiv $ \deriv -> case deriv of HsDerivingClause { deriv_clause_strategy, deriv_clause_tys } -> do traverse_ @Maybe registerHdkA deriv_clause_strategy deriv_clause_tys' <- - delimitHdkA (getLoc deriv_clause_tys) $ + extendHdkA (getLoc deriv_clause_tys) $ for @Located deriv_clause_tys addHaddock pure HsDerivingClause { deriv_clause_ext = noExtField, @@ -645,7 +693,7 @@ instance HasHaddock (LHsSigType GhcPs) where instance HasHaddock (LHsType GhcPs) where addHaddock ltype = - delimitHdkA (getLoc ltype) $ + extendHdkA (getLoc ltype) $ for @Located ltype $ \t -> case t of HsForAllTy _ fvf bndrs body -> do @@ -888,7 +936,11 @@ flattenBindsAndSigs [LTyFamInstDecl GhcPs], [LDataFamInstDecl GhcPs], [LDocDecl]) -> [LHsDecl GhcPs] flattenBindsAndSigs (all_bs, all_ss, all_ts, all_tfis, all_dfis, all_docs) = - mergeListsBy cmp [ + -- 'cmpBufSpan' is safe here with the following assumptions: + -- + -- * 'LHsDecl' produced by 'decl_cls' in Parser.y always have a 'BufSpan' + -- * 'partitionBindsAndSigs' does not discard this 'BufSpan' + mergeListsBy cmpBufSpan [ map_l (\b -> ValD noExtField b) (bagToList all_bs), map_l (\s -> SigD noExtField s) all_ss, map_l (\t -> TyClD noExtField (FamDecl noExtField t)) all_ts, @@ -897,10 +949,5 @@ flattenBindsAndSigs (all_bs, all_ss, all_ts, all_tfis, all_dfis, all_docs) = map_l (\d -> DocD noExtField d) all_docs ] where - cmp :: LHsDecl GhcPs -> LHsDecl GhcPs -> Ordering - cmp (L (getBufSpan -> Just a) _) (L (getBufSpan -> Just b) _) = - compare a b - cmp _ _ = panic "flattenBindsAndSigs: HsDecl without BufSpan" - map_l :: (a -> b) -> [Located a] -> [Located b] map_l f = map (mapLoc f) ===================================== compiler/utils/Util.hs ===================================== @@ -54,6 +54,7 @@ module Util ( whenNonEmpty, mergeListsBy, + isSorted, -- * Tuples fstOf3, sndOf3, thdOf3, @@ -617,16 +618,19 @@ whenNonEmpty (x:xs) f = f (x :| xs) -- | Merge an unsorted list of sorted lists, for example: -- -- mergeListsBy compare [ [2,5,15], [1,10,100] ] = [1,2,5,10,15,100] ] +-- +-- O(n log k) mergeListsBy :: forall a. (a -> a -> Ordering) -> [[a]] -> [a] mergeListsBy cmp lists | debugIsOn, not (all sorted lists) = -- When debugging is on, we check that the input lists are sorted. panic "mergeListsBy: input lists must be sorted" - where - sorted [] = True - sorted [_] = True - sorted (x:y:xs) = cmp x y /= GT && sorted (y:xs) + where sorted = isSorted cmp mergeListsBy cmp all_lists = merge_lists all_lists where + -- Implements "Iterative 2-Way merge" described at + -- https://en.wikipedia.org/wiki/K-way_merge_algorithm + + -- Merge two sorted lists into one in O(n). merge2 :: [a] -> [a] -> [a] merge2 [] ys = ys merge2 xs [] = xs @@ -635,12 +639,17 @@ mergeListsBy cmp all_lists = merge_lists all_lists GT -> y : merge2 (x:xs) ys _ -> x : merge2 xs (y:ys) + -- Merge the first list with the second, the third with the fourth, and so + -- on. The output has half as much lists as the input. merge_neighbours :: [[a]] -> [[a]] merge_neighbours [] = [] merge_neighbours [xs] = [xs] merge_neighbours (xs : ys : lists) = merge2 xs ys : merge_neighbours lists + -- Since 'merge_neighbours' halves the amount of lists in each iteration, + -- we perform O(log k) iteration. Each iteration is O(n). The total running + -- time is therefore O(n log k). merge_lists :: [[a]] -> [a] merge_lists lists = case merge_neighbours lists of @@ -648,6 +657,12 @@ mergeListsBy cmp all_lists = merge_lists all_lists [xs] -> xs lists' -> merge_lists lists' +isSorted :: (a -> a -> Ordering) -> [a] -> Bool +isSorted cmp = sorted + where + sorted [] = True + sorted [_] = True + sorted (x:y:xs) = cmp x y /= GT && sorted (y:xs) {- ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b204b5b404a26b794f9ff9893463bd2f95b1b811 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b204b5b404a26b794f9ff9893463bd2f95b1b811 You're receiving 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 21 23:06:27 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 21 Apr 2020 19:06:27 -0400 Subject: [Git][ghc/ghc][wip/runRW] 2 commits: Make Lint check return type of a join point Message-ID: <5e9f7c73cd8e1_61673f8199536d946300253@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 5736297f by Simon Peyton Jones at 2020-04-22T00:06:23+01:00 Make Lint check return type of a join point Consider join x = rhs in body It's important that the type of 'rhs' is the same as the type of 'body', but Lint wasn't checking that invariant. Now it does! This was exposed by investigation into !3113. - - - - - cb9824a6 by Simon Peyton Jones at 2020-04-22T00:06:23+01:00 Do not float join points in exprIsConApp_maybe We hvae been making exprIsConApp_maybe cleverer in recent times: commit b78cc64e923716ac0512c299f42d4d0012306c05 Date: Thu Nov 15 17:14:31 2018 +0100 Make constructor wrappers inline only during the final phase commit 7833cf407d1f608bebb1d38bb99d3035d8d735e6 Date: Thu Jan 24 17:58:50 2019 +0100 Look through newtype wrappers (Trac #16254) commit c25b135ff5b9c69a90df0ccf51b04952c2dc6ee1 Date: Thu Feb 21 12:03:22 2019 +0000 Fix exprIsConApp_maybe But alas there was still a bug, now immortalised in Note [Don't float join points] in SimpleOpt. It's quite hard to trigger because it requires a dead join point, but it came up when compiling Cabal Cabal.Distribution.Fields.Lexer.hs, when working on !3113. Happily, the fix is extremly easy. Finding the bug was not so easy. - - - - - 2 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/SimpleOpt.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -461,7 +461,7 @@ lintCoreBindings dflags pass local_in_scope binds addLoc TopLevelBindings $ do { checkL (null dups) (dupVars dups) ; checkL (null ext_dups) (dupExtVars ext_dups) - ; lintRecBindings TopLevel all_pairs $ + ; lintRecBindings TopLevel all_pairs $ \_ -> return () } where all_pairs = flattenBinds binds @@ -572,11 +572,11 @@ Check a core binding, returning the list of variables bound. -} lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)] - -> LintM a -> LintM a + -> ([LintedId] -> LintM a) -> LintM a lintRecBindings top_lvl pairs thing_inside = lintIdBndrs top_lvl bndrs $ \ bndrs' -> do { zipWithM_ lint_pair bndrs' rhss - ; thing_inside } + ; thing_inside bndrs' } where (bndrs, rhss) = unzip pairs lint_pair bndr' rhs @@ -584,6 +584,12 @@ lintRecBindings top_lvl pairs thing_inside do { rhs_ty <- lintRhs bndr' rhs -- Check the rhs ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty } +lintLetBody :: [LintedId] -> CoreExpr -> LintM LintedType +lintLetBody bndrs body + = do { body_ty <- addLoc (BodyOfLetRec bndrs) (lintCoreExpr body) + ; mapM_ (lintJoinBndrType body_ty) bndrs + ; return body_ty } + lintLetBind :: TopLevelFlag -> RecFlag -> LintedId -> CoreExpr -> LintedType -> LintM () -- Binder's type, and the RHS, have already been linted @@ -839,7 +845,7 @@ lintCoreExpr (Let (NonRec bndr rhs) body) -- Now lint the binder ; lintBinder LetBind bndr $ \bndr' -> do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty - ; addLoc (BodyOfLetRec [bndr]) (lintCoreExpr body) } } + ; lintLetBody [bndr'] body } } | otherwise = failWithL (mkLetErr bndr rhs) -- Not quite accurate @@ -856,9 +862,8 @@ lintCoreExpr e@(Let (Rec pairs) body) ; checkL (all isJoinId bndrs || all (not . isJoinId) bndrs) $ mkInconsistentRecMsg bndrs - ; lintRecBindings NotTopLevel pairs $ - addLoc (BodyOfLetRec bndrs) $ - lintCoreExpr body } + ; lintRecBindings NotTopLevel pairs $ \ bndrs' -> + lintLetBody bndrs' body } where bndrs = map fst pairs @@ -972,6 +977,25 @@ checkDeadIdOcc id = return () ------------------ +lintJoinBndrType :: LintedType -- Type of the body + -> LintedId -- Possibly a join Id + -> LintM () +-- Checks that the return type of a join Id matches the body +-- E.g. join j x = rhs in body +-- The type of 'rhs' must be the same as the type of 'body' +lintJoinBndrType body_ty bndr + | Just arity <- isJoinId_maybe bndr + , let bndr_ty = idType bndr + , (bndrs, res) <- splitPiTys bndr_ty + = checkL (length bndrs >= arity + && body_ty `eqType` mkPiTys (drop arity bndrs) res) $ + hang (text "Join point returns different type than body") + 2 (vcat [ text "Join bndr:" <+> ppr bndr <+> dcolon <+> ppr (idType bndr) + , text "Join arity:" <+> ppr arity + , text "Body type:" <+> ppr body_ty ]) + | otherwise + = return () + checkJoinOcc :: Id -> JoinArity -> LintM () -- Check that if the occurrence is a JoinId, then so is the -- binding site, and it's a valid join Id ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -949,6 +949,31 @@ exprIsConApp_maybe does not return Just) then nothing happens, and nothing will happen the next time either. See test T16254, which checks the behavior of newtypes. + +Note [Don't float join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +exprIsConApp_maybe should succeed on + let v = e in Just v +returning [x=e] as one of the [FloatBind]. But it must +NOT succeed on + join j x = rhs in Just v +because join-points can't be gaily floated. Consider + case (join j x = rhs in Just) of + K p q -> blah +We absolutely must not "simplify" this to + join j x = rhs + in blah +because j's return type is (Maybe t), quite different to blah's. + +You might think this could never happen, because j can't be +tail-called in the body if the body returns a constructor. But +in !3113 we had a /dead/ join point (which is not illegal), +and its return type was wonky. + +The simple thing is not to float a join point. The next iteration +of the simplifier will sort everything out. And it there is +a join point, the chances are that the body is not a constructor +application, so failing faster is good. -} data ConCont = CC [CoreExpr] Coercion @@ -1004,6 +1029,8 @@ exprIsConApp_maybe (in_scope, id_unf) expr in go subst' (float:floats) body (CC args co) go subst floats (Let (NonRec bndr rhs) expr) cont + | not (isJoinId bndr) + -- Crucial guard! See Note [Don't float join points] = let rhs' = subst_expr subst rhs (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' rhs') View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c1f35320a1ee3885ff8291cac9dfeefb6b32fb06...cb9824a6d725ec932b4531641f3b23cef2b3fecb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c1f35320a1ee3885ff8291cac9dfeefb6b32fb06...cb9824a6d725ec932b4531641f3b23cef2b3fecb You're receiving 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 22 09:50:33 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 22 Apr 2020 05:50:33 -0400 Subject: [Git][ghc/ghc][wip/runRW] Improve the rule for runRW# Message-ID: <5ea01369a7fe4_6167134ebbc46344159@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 1e09f7bf by Simon Peyton Jones at 2020-04-22T10:49:28+01:00 Improve the rule for runRW# Now it does not require a lambda as the argument of runRW# - - - - - 1 changed file: - compiler/GHC/Core/Opt/Simplify.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -37,6 +37,7 @@ import GHC.Core.DataCon , StrictnessMark (..) ) import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) ) import GHC.Core +import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) import GHC.Builtin.Names( runRWKey ) import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) @@ -1852,20 +1853,6 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_strs = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont --- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o --- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) -rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont - | fun `hasKey` runRWKey - , [ ValArg (Lam s body) - , TyArg {}, TyArg {} ] <- rev_args - = do { (env', s') <- simplLamBndr (zapSubstEnv env) s - ; body' <- simplExprC env' body cont - ; let arg' = Lam s' body' - ty' = contResultType cont - rr' = getRuntimeRep ty' - call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] - ; return (emptyFloats env, call') } - ---------- Try rewrite RULES -------------- -- See Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args @@ -1936,6 +1923,25 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty -- It's worth an 18% improvement in allocation for this -- particular benchmark; 5% on 'mate' and 1.3% on 'multiplier' +---------- The runRW# rule. Do this after absorbing all arguments ------ +-- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o +-- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` runRWKey + , not (contIsStop cont) -- Don't fiddle around if the continuation is boring + , [ ValArg arg + , TyArg {}, TyArg {} ] <- rev_args + = do { s <- newId (fsLit "s") realWorldStatePrimTy + ; let env' = zapSubstEnv env `addNewInScopeIds` [s] + cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s + , sc_env = env', sc_cont = cont } + ; body' <- simplExprC env' arg cont' + ; let arg' = Lam s body' + ty' = contResultType cont + rr' = getRuntimeRep ty' + call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] + ; return (emptyFloats env, call') } + ---------- No further useful info, revert to generic rebuild ------------ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e09f7bf7235e2a2e7cb54a21b2b3aa4f7497b5f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e09f7bf7235e2a2e7cb54a21b2b3aa4f7497b5f You're receiving 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 22 10:20:08 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 22 Apr 2020 06:20:08 -0400 Subject: [Git][ghc/ghc][wip/runRW] Further improvement to the runRW# rule Message-ID: <5ea01a581293b_61673f81ef22dee4635281d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: fad536ea by Simon Peyton Jones at 2020-04-22T11:19:40+01:00 Further improvement to the runRW# rule Now we avoid repeated simplification - - - - - 1 changed file: - compiler/GHC/Core/Opt/Simplify.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -1880,14 +1880,36 @@ rebuildCall env info (CastIt co cont) rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) = rebuildCall env (addTyArgTo info arg_ty) cont -rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty +---------- The runRW# rule. Do this after absorbing all arguments ------ +-- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o +-- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) + (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) + | fun `hasKey` runRWKey + , not (contIsStop cont) -- Don't fiddle around if the continuation is boring + , [ TyArg {}, TyArg {} ] <- rev_args + = do { s <- newId (fsLit "s") realWorldStatePrimTy + ; let env' = (arg_se `setInScopeFromE` env) `addNewInScopeIds` [s] + cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s + , sc_env = env', sc_cont = cont } + ; body' <- simplExprC env' arg cont' + ; let arg' = Lam s body' + ty' = contResultType cont + rr' = getRuntimeRep ty' + call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] + ; return (emptyFloats env, call') } + +rebuildCall env info@(ArgInfo { ai_type = fun_ty, ai_encl = encl_rules , ai_strs = str:strs, ai_discs = disc:discs }) (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_cont = cont }) + + -- Argument is already simplified | isSimplified dup_flag -- See Note [Avoid redundant simplification] = rebuildCall env (addValArgTo info' arg) cont - | str -- Strict argument + -- Strict arguments + | str , sm_case_case (getMode env) = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $ simplExprF (arg_se `setInScopeFromE` env) arg @@ -1895,7 +1917,8 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty , sc_dup = Simplified, sc_cont = cont }) -- Note [Shadowing] - | otherwise -- Lazy argument + -- Lazy arguments + | otherwise -- DO NOT float anything outside, hence simplExprC -- There is no benefit (unlike in a let-binding), and we'd -- have to be very careful about bogus strictness through @@ -1923,25 +1946,6 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty -- It's worth an 18% improvement in allocation for this -- particular benchmark; 5% on 'mate' and 1.3% on 'multiplier' ----------- The runRW# rule. Do this after absorbing all arguments ------ --- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o --- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) -rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont - | fun `hasKey` runRWKey - , not (contIsStop cont) -- Don't fiddle around if the continuation is boring - , [ ValArg arg - , TyArg {}, TyArg {} ] <- rev_args - = do { s <- newId (fsLit "s") realWorldStatePrimTy - ; let env' = zapSubstEnv env `addNewInScopeIds` [s] - cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s - , sc_env = env', sc_cont = cont } - ; body' <- simplExprC env' arg cont' - ; let arg' = Lam s body' - ty' = contResultType cont - rr' = getRuntimeRep ty' - call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] - ; return (emptyFloats env, call') } - ---------- No further useful info, revert to generic rebuild ------------ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fad536ea7e2622fb1102df55bd642b4153603503 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fad536ea7e2622fb1102df55bd642b4153603503 You're receiving 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 22 16:33:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 22 Apr 2020 12:33:22 -0400 Subject: [Git][ghc/ghc][ghc-8.8] Stack: fix name mangling. Message-ID: <5ea071d27a137_616765c7a2864718f1@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.8 at Glasgow Haskell Compiler / GHC Commits: 3306cd5c by Tamar Christina at 2020-04-22T12:32:54-04:00 Stack: fix name mangling. (cherry picked from commit fb031b9b046e48ffe0d2864ec76bee3bc8ff5625) - - - - - 4 changed files: - compiler/nativeGen/X86/Instr.hs - + testsuite/tests/profiling/should_compile/T16166/Main.hs - + testsuite/tests/profiling/should_compile/T16166/NetworkRequestHeader.hs - + testsuite/tests/profiling/should_compile/T16166/all.T Changes: ===================================== compiler/nativeGen/X86/Instr.hs ===================================== @@ -942,7 +942,7 @@ x86_mkStackAllocInstr platform amount ] ArchX86_64 | needs_probe_call platform amount -> [ MOV II64 (OpImm (ImmInt amount)) (OpReg rax) - , CALL (Left $ strImmLit "__chkstk_ms") [rax] + , CALL (Left $ strImmLit "___chkstk_ms") [rax] , SUB II64 (OpReg rax) (OpReg rsp) ] | otherwise -> ===================================== testsuite/tests/profiling/should_compile/T16166/Main.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE BangPatterns #-} +-- Main.hs +module Main (main) where + +import NetworkRequestHeader + +import Control.Monad + +main :: IO () +main = void $ parseHeaderLines [] + ===================================== testsuite/tests/profiling/should_compile/T16166/NetworkRequestHeader.hs ===================================== @@ -0,0 +1,76 @@ +{-# LANGUAGE BangPatterns #-} +-- NetworkRequestHeader.hs +module NetworkRequestHeader (parseHeaderLines, parseRequestLine) where + +import Control.Exception +import Control.Monad +import Data.ByteString.Internal (ByteString(..), memchr) +import Data.Word +import Foreign.ForeignPtr (withForeignPtr) +import Foreign.Ptr (Ptr, plusPtr, minusPtr, nullPtr) +import Foreign.Storable (peek) + +-- | Error types for bad 'Request'. +data InvalidRequest = NonHttp + +instance Show InvalidRequest where show _ = "" +instance Exception InvalidRequest + +parseHeaderLines :: [ByteString] + -> IO (ByteString + ,ByteString -- Path + ,ByteString -- Path, parsed + ) +parseHeaderLines [] = throwIO $ NonHttp +parseHeaderLines (firstLine:_) = do + (method, path') <- parseRequestLine firstLine + let path = path' + return (method, path', path) + +parseRequestLine :: ByteString + -> IO (ByteString + ,ByteString) +parseRequestLine (PS fptr off len) = withForeignPtr fptr $ \ptr -> do + when (len < 14) $ throwIO NonHttp + let methodptr = ptr `plusPtr` off + limptr = methodptr `plusPtr` len + lim0 = fromIntegral len + + pathptr0 <- memchr methodptr 32 lim0 -- ' ' + when (pathptr0 == nullPtr || (limptr `minusPtr` pathptr0) < 11) $ + throwIO NonHttp + let pathptr = pathptr0 `plusPtr` 1 + lim1 = fromIntegral (limptr `minusPtr` pathptr0) + + httpptr0 <- memchr pathptr 32 lim1 -- ' ' + when (httpptr0 == nullPtr || (limptr `minusPtr` httpptr0) < 9) $ + throwIO NonHttp + let httpptr = httpptr0 `plusPtr` 1 + lim2 = fromIntegral (httpptr0 `minusPtr` pathptr) + + checkHTTP httpptr + queryptr <- memchr pathptr 63 lim2 -- '?' + + let !method = bs ptr methodptr pathptr0 + !path + | queryptr == nullPtr = bs ptr pathptr httpptr0 + | otherwise = bs ptr pathptr queryptr + + return (method,path) + where + check :: Ptr Word8 -> Int -> Word8 -> IO () + check p n w = do + w0 <- peek $ p `plusPtr` n + when (w0 /= w) $ throwIO NonHttp + checkHTTP httpptr = do + check httpptr 0 72 -- 'H' + check httpptr 1 84 -- 'T' + check httpptr 2 84 -- 'T' + check httpptr 3 80 -- 'P' + check httpptr 4 47 -- '/' + check httpptr 6 46 -- '.' + bs ptr p0 p1 = PS fptr o l + where + o = p0 `minusPtr` ptr + l = p1 `minusPtr` p0 + ===================================== testsuite/tests/profiling/should_compile/T16166/all.T ===================================== @@ -0,0 +1,7 @@ +# We need the register allocator to use more than a page worth of stack space +# when spilling in a single function, easiest way to do that is +# using a profiling build +test('T16166', [only_ways(['normal']), req_profiling, + extra_files(['Main.hs', 'NetworkRequestHeader.hs'])], + multimod_compile, + ['Main NetworkRequestHeader', '-O -prof -fprof-auto -v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3306cd5c16f71684bd49c338d5a2b1981197ffc3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3306cd5c16f71684bd49c338d5a2b1981197ffc3 You're receiving 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 22 16:34:41 2020 From: gitlab at gitlab.haskell.org (cgibbard) Date: Wed, 22 Apr 2020 12:34:41 -0400 Subject: [Git][ghc/ghc][wip/ttg-con-pat] 8 commits: docs: drop note about not supporting shared libraries on unix systems Message-ID: <5ea07221a977d_616776d1c7464720a@gitlab.haskell.org.mail> cgibbard pushed to branch wip/ttg-con-pat at Glasgow Haskell Compiler / GHC Commits: bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - 495f1666 by John Ericson at 2020-04-22T12:34:39-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.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/e0df84fd2e842bc096ddd8bb858c32535af67c5a...495f1666683155b9e6e30161438a5ff85ef01fcc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0df84fd2e842bc096ddd8bb858c32535af67c5a...495f1666683155b9e6e30161438a5ff85ef01fcc You're receiving 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 22 20:18:24 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 22 Apr 2020 16:18:24 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] stuff Message-ID: <5ea0a690657e2_61673f81ba8fd5246541574@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: fdaaeee5 by Sebastian Graf at 2020-04-22T22:18:18+02:00 stuff - - - - - 4 changed files: - compiler/GHC/Core/Op/CprAnal.hs - compiler/GHC/Core/Op/WorkWrap/Lib.hs - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/Op/CprAnal.hs ===================================== @@ -138,12 +138,12 @@ cprAnal, cprAnal' -> CoreExpr -- ^ expression to be denoted by a 'CprType' -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType' -cprAnal env args e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ +cprAnal env args e = pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ cprAnal' env args e -cprAnal' _ _ (Lit lit) = (topCprType, Lit lit) -cprAnal' _ _ (Type ty) = (topCprType, Type ty) -- Doesn't happen, in fact -cprAnal' _ _ (Coercion co) = (topCprType, Coercion co) +cprAnal' _ _ (Lit lit) = (whnfTermCprType, Lit lit) +cprAnal' _ _ (Type ty) = (whnfTermCprType, Type ty) -- Doesn't happen, in fact +cprAnal' _ _ (Coercion co) = (whnfTermCprType, Coercion co) cprAnal' env args (Var var) = (cprTransform env args var, Var var) ===================================== compiler/GHC/Core/Op/WorkWrap/Lib.hs ===================================== @@ -1081,25 +1081,25 @@ mkWWcpr_one_layer fam_envs body_ty cpr = runMaybeT $ do uniq1:arg_uniqs <- lift getUniquesM let arg_vars = zipWith mk_ww_local arg_uniqs arg_tys - maybe_arg_stuff <- lift $ zipWithM (mkWWcpr_one_layer fam_envs) - (map fst arg_tys) - arg_cprs + maybe_arg_builders <- lift $ zipWithM (mkWWcpr_one_layer fam_envs) + (map fst arg_tys) + arg_cprs - let go_arg_stuff var mb_stuff = - case mb_stuff of + let go_arg_stuff var mb_builder = + case mb_builder of Nothing -> -- this argument does not need to be deconstructed further ([var], varToCoreExpr var, id) Just (inner_vars, arg_con, arg_decon) -> (inner_vars, arg_con, arg_decon (varToCoreExpr var)) - let (inner_arg_varss, arg_cons, arg_decons) = unzip3 $ zipWith go_arg_stuff arg_vars maybe_arg_stuff + let (inner_arg_varss, arg_cons, arg_decons) = unzip3 $ zipWith go_arg_stuff arg_vars maybe_arg_builders inner_arg_vars = concat inner_arg_varss inner_decon = foldl' (.) id arg_decons -- Don't try to WW an unboxed tuple return type when there's nothing inside -- to unbox further. - guard (not (isUnboxedTupleCon data_con && all isNothing maybe_arg_stuff)) + guard (not (isUnboxedTupleCon data_con && all isNothing maybe_arg_builders)) return ( inner_arg_vars , mkConApp data_con (map Type inst_tys ++ arg_cons) `mkCast` mkSymCo co ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -4,13 +4,14 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE GeneralisedNewtypeDeriving #-} +{-# LANGUAGE PatternSynonyms #-} -- | Types for the Constructed Product Result lattice. "GHC.Core.Op.CprAnal" -- and "GHC.Core.Op.WorkWrap.Lib" are its primary customers via 'idCprInfo'. module GHC.Types.Cpr ( TerminationFlag (Terminates), - Cpr, topCpr, botCpr, conCpr, initRecFunCpr, lubCpr, asConCpr, - CprType (..), topCprType, botCprType, lubCprType, conCprType, + Cpr, topCpr, botCpr, conCpr, whnfTermCpr, initRecFunCpr, lubCpr, asConCpr, + CprType (..), topCprType, botCprType, whnfTermCprType, conCprType, lubCprType, pruneDeepCpr, markConCprType, splitConCprTy, applyCprTy, abstractCprTy, abstractCprTyNTimes, ensureCprTyArity, trimCprTy, forceCprTy, forceCpr, bothCprType, @@ -99,15 +100,11 @@ lubTermFlag _ MightDiverge = MightDiverge lubTermFlag Terminates Terminates = Terminates data Termination - = Term !TerminationFlag !(Levitated (KnownShape Termination)) + = Term_ !TerminationFlag !(Levitated (KnownShape Termination)) + -- Don't use 'Term_', use 'Term' instead! Otherwise the derived Eq instance + -- is broken. deriving Eq -botTerm :: Termination -botTerm = Term Terminates Bot - -topTerm :: Termination -topTerm = Term MightDiverge Top - -- | Normalise the nested termination info according to -- > Top === Levitate (Con t [topTerm..]) -- > Bot === Levitate (Con t [botTerm..]) @@ -118,14 +115,27 @@ normTermShape (Levitate (Con _ fields)) | all (== botTerm) fields = Bot normTermShape l_sh = l_sh +pattern Term :: TerminationFlag -> Levitated (KnownShape Termination) -> Termination +pattern Term tf l <- (Term_ tf l) + where + Term tf l = Term_ tf (normTermShape l) + +{-# COMPLETE Term #-} + +botTerm :: Termination +botTerm = Term Terminates Bot + +topTerm :: Termination +topTerm = Term MightDiverge Top + lubTerm :: Termination -> Termination -> Termination lubTerm (Term tf1 l_sh1) (Term tf2 l_sh2) = Term (lubTermFlag tf1 tf2) - (normTermShape (lubLevitated (lubKnownShape lubTerm) l_sh1 l_sh2)) + (lubLevitated (lubKnownShape lubTerm) l_sh1 l_sh2) pruneDeepTerm :: Int -> Termination -> Termination pruneDeepTerm depth (Term tf (Levitate sh)) - = Term tf (normTermShape (pruneKnownShape pruneDeepTerm depth sh)) + = Term tf (pruneKnownShape pruneDeepTerm depth sh) pruneDeepTerm _ term = term seqTerm :: Termination -> () @@ -163,15 +173,27 @@ seqTerm (Term _ l) = seqLevitated (seqKnownShape seqTerm) l data Cpr = Cpr !TerminationFlag !(Levitated (KnownShape Cpr)) - | NoMoreCpr !Termination + | NoMoreCpr_ !Termination deriving Eq +pattern NoMoreCpr :: Termination -> Cpr +pattern NoMoreCpr t <- (NoMoreCpr_ t) + where + NoMoreCpr (Term MightDiverge Top) = topCpr + NoMoreCpr (Term Terminates Bot) = botCpr + NoMoreCpr t = NoMoreCpr_ t + +{-# COMPLETE Cpr, NoMoreCpr #-} + botCpr :: Cpr botCpr = Cpr Terminates Bot topCpr :: Cpr topCpr = Cpr MightDiverge Top +whnfTermCpr :: Cpr +whnfTermCpr = Cpr Terminates Top + -- | The initial termination of a recursive function in fixed-point iteration. -- We assume a recursive call 'MightDiverge', but are optimistic about all -- CPR and nested termination information. I.e., we assume that evaluating @@ -245,6 +267,9 @@ topCprType = CprType 0 topCpr botCprType :: CprType botCprType = CprType 0 botCpr +whnfTermCprType :: CprType +whnfTermCprType = CprType 0 whnfTermCpr + lubCprType :: CprType -> CprType -> CprType lubCprType ty1@(CprType n1 cpr1) ty2@(CprType n2 cpr2) | ct_cpr ty1 == botCpr && n1 <= n2 = ty2 @@ -506,6 +531,9 @@ type UnboxingStrategy = Type -> Demand -> Maybe (DataCon, [Type], [Demand]) -- - A call demand @C(S)@ would translate to @strTop -> #(#,*)@ argCprTypesFromStrictSig :: UnboxingStrategy -> [Type] -> StrictSig -> [CprType] argCprTypesFromStrictSig want_to_unbox arg_tys sig + -- TODO: Maybe look at unliftedness from the unboxing strategy, just in case + -- we e.g. fail to mark an Int# argument as Terminates, which should always be + -- the case as per the let/app invariant. = zipWith go arg_tys (argDmdsFromStrictSig sig) where go arg_ty arg_dmd @@ -539,8 +567,11 @@ instance Outputable Termination where Levitate shape -> ppr shape instance Outputable Cpr where - ppr (NoMoreCpr t) = ppr t - ppr (Cpr tf l) = ppr tf <> case l of + ppr (NoMoreCpr t) = ppr t + -- I like it better without the special case + -- ppr (Cpr MightDiverge Top) = empty + -- ppr (Cpr Terminates Bot) = char 'b' + ppr (Cpr tf l) = ppr tf <> case l of Top -> empty Bot -> char 'b' Levitate shape -> char 'c' <> ppr shape ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -1178,8 +1178,8 @@ mkPrimOpId prim_op id = mkGlobalId (PrimOpId prim_op) name ty info -- PrimOps don't ever construct a product, but we want to preserve bottoms - cpr | isBotDiv (snd (splitStrictSig strict_sig)) = botCpr - | otherwise = topCpr + cpr | isBotDiv (snd (splitStrictSig strict_sig)) = initRecFunCpr + | otherwise = whnfTermCpr info = noCafIdInfo `setRuleInfo` mkRuleInfo (maybeToList $ primOpRules name prim_op) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdaaeee50f83688932aff91997b92d02408ae498 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdaaeee50f83688932aff91997b92d02408ae498 You're receiving 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 22 20:39:39 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 16:39:39 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 24 commits: docs: drop note about not supporting shared libraries on unix systems Message-ID: <5ea0ab8bd3906_6167865d29c6558095@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - a28cdfae by Takenobu Tani at 2020-04-22T16:39:00-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - 00953e0f by Jonathan DK Gibbons at 2020-04-22T16:39:02-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - 1f287263 by John Ericson at 2020-04-22T16:39:02-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - 056ea170 by John Ericson at 2020-04-22T16:39:02-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - cb20127c by John Ericson at 2020-04-22T16:39:02-04:00 Generalize type of `matchCanFail` - - - - - 860baf0d by John Ericson at 2020-04-22T16:39:02-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6dcd67c4 by Alexis King at 2020-04-22T16:39:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - b327821c by Roland Senn at 2020-04-22T16:39:18-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 895c1d14 by Peter Trommler at 2020-04-22T16:39:18-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - 18980390 by Simon Peyton Jones at 2020-04-22T16:39:19-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 56b1af0d by Ben Gamari at 2020-04-22T16:39:20-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - 306ba283 by Andreas Klebinger at 2020-04-22T16:39:20-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 1a40315c by Ben Gamari at 2020-04-22T16:39:21-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - f30a3107 by Moritz Angermann at 2020-04-22T16:39:21-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - 90aa0d63 by Ryan Scott at 2020-04-22T16:39:22-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 0e70af26 by Ömer Sinan Ağacan at 2020-04-22T16:39:27-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - ce47e6b4 by Sylvain Henry at 2020-04-22T16:39:31-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/226a97320f1a34173b96f6658b137c3a528ebd55...ce47e6b489bf021c3093d8f90115ab04ba7694b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/226a97320f1a34173b96f6658b137c3a528ebd55...ce47e6b489bf021c3093d8f90115ab04ba7694b5 You're receiving 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 22 23:36:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 22 Apr 2020 19:36:04 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5ea0d4e45616_61673f8199536d946595751@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: 9f8e0e9c by Ben Gamari at 2020-04-22T19:35:19-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 10 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +flushEventLog :: IO () +flushEventLog = c_flushEventLog nullPtr + +foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO () ===================================== rts/Capability.c ===================================== @@ -23,6 +23,7 @@ #include "Schedule.h" #include "Sparks.h" #include "Trace.h" +#include "eventlog/EventLog.h" // for flushLocalEventsBuf #include "sm/GC.h" // for gcWorkerThread() #include "STM.h" #include "RtsUtils.h" @@ -885,6 +886,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushAllCapsEventsBufs(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/Trace.h ===================================== @@ -319,7 +319,6 @@ void traceConcSweepEnd(void); void traceConcUpdRemSetFlush(Capability *cap); void traceNonmovingHeapCensus(uint32_t log_blk_size, const struct NonmovingAllocCensus *census); - void flushTrace(void); #else /* !TRACING */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -16,6 +16,7 @@ #include "RtsUtils.h" #include "Stats.h" #include "EventLog.h" +#include "Schedule.h" #include #include @@ -271,7 +272,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1566,40 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +// Flush all capabilities' event buffers when we already hold all capabilities. +// Used during forkProcess. +void flushAllCapsEventsBufs() +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + + for (int i=0; i < n_capabilities; i++) { + flushLocalEventsBuf(capabilities[i]); + } + flushEventLogWriter(); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = getTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) @@ -1578,4 +1613,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { void endEventLogging(void) {} +void flushEventLog(Capability **cap STG_UNUSED) {} + #endif /* TRACING */ ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,11 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllCapsEventsBufs(void); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event @@ -175,6 +178,9 @@ void postNonmovingHeapCensus(int log_blk_size, #else /* !TRACING */ +INLINE_HEADER void flushLocalEventsBuf(Capability *cap) +{ /* nothing */ } + INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, EventTypeNum tag STG_UNUSED, StgThreadID id STG_UNUSED, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f8e0e9c4f76f00318e3d628fcfd9e67297409d0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f8e0e9c4f76f00318e3d628fcfd9e67297409d0 You're receiving 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 23 03:09:55 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:09:55 -0400 Subject: [Git][ghc/ghc][master] stg-spec: Modify file paths according to new module hierarchy Message-ID: <5ea1070332d4e_61673f81afeb5fbc6603620@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - 2 changed files: - docs/stg-spec/StgSyn.ott - docs/stg-spec/stg-spec.mng Changes: ===================================== docs/stg-spec/StgSyn.ott ===================================== @@ -28,13 +28,13 @@ indexvar i, j, k, n ::= {{ com Indices to be used in lists }} grammar lit {{ tex \textsf{lit} }} :: 'Literal_' ::= - {{ com Literals, \coderef{basicTypes/Literal.hs}{Literal} }} + {{ com Literals, \coderef{GHC/Types/Literal.hs}{Literal} }} op {{ tex \textsf{op} }} :: 'StgOp_' ::= - {{ com Primitive operation or foreign call, \coderef{stgSyn/StgSyn.hs}{StgOp} }} + {{ com Primitive operation or foreign call, \coderef{GHC/Stg/Syntax.hs}{StgOp} }} cc {{ tex \textsf{cc} }} :: 'CostCentre_' ::= - {{ com Cost-centre, \coderef{profiling/CostCentre.hs}{CostCentre} }} + {{ com Cost-centre, \coderef{GHC/Types/CostCentre.hs}{CostCentre} }} ccs {{ tex \textsf{ccs} }} :: 'CostCentreStack_' ::= | CCCS :: :: CurrentCCS {{ com Current cost-centre stack }} @@ -42,9 +42,9 @@ ccs {{ tex \textsf{ccs} }} :: 'CostCentreStack_' ::= | _ :: :: DontCareCCS {{ com Don't care cost-centre stack }} | ccs ^ ccs' :: :: EnterFunCCS {{ com Function entry, \coderef{rts/Profiling.c}{enterFunCCS} }} | ccs # cc :: :: PushCC {{ com Push a cost-centre, \coderef{rts/Profiling.c}{pushCostCentre} }} - {{ com Cost-centre stack, \coderef{profiling/CostCentre.hs}{CostCentreStack} }} + {{ com Cost-centre stack, \coderef{GHC/Types/CostCentre.hs}{CostCentreStack} }} -a, b, c :: 'StgArg_' ::= {{ com Arguments, \coderef{stgSyn/StgSyn.hs}{StgArg} }} +a, b, c :: 'StgArg_' ::= {{ com Arguments, \coderef{GHC/Stg/Syntax.hs}{StgArg} }} | x :: :: StgVarArg {{ com Variable }} | lit :: :: StgLitArg {{ com Literal }} @@ -59,7 +59,7 @@ xs :: 'Ids_' ::= {{ com List of variables }} | nil :: :: EmptyList | xs xs' :: :: Append -e :: 'StgExpr_' ::= {{ com Expressions, \coderef{stgSyn/StgSyn.hs}{StgExpr} }} +e :: 'StgExpr_' ::= {{ com Expressions, \coderef{GHC/Stg/Syntax.hs}{StgExpr} }} | lit :: :: StgLit {{ com Literal }} | x args :: :: StgApp {{ com Function application (or variable) }} | K args :: :: StgConApp {{ com Saturated constructor application }} @@ -75,23 +75,23 @@ subst :: 'Subst_' ::= {{ com List of substitutions }} | [ a / x ] :: :: Mapping | :: :: List -binding :: 'StgBind_' ::= {{ com Let-bindings, \coderef{stgSyn/StgSyn.hs}{StgBind} }} +binding :: 'StgBind_' ::= {{ com Let-bindings, \coderef{GHC/Stg/Syntax.hs}{StgBind} }} | x = rhs :: :: StgNonRec {{ com Non-recursive binding }} | rec :: :: StgRec {{ com Recursive binding }} -upd :: 'UpdateFlag_' ::= {{ com Update flag, \coderef{stgSyn/StgSyn.hs}{UpdateFlag} }} +upd :: 'UpdateFlag_' ::= {{ com Update flag, \coderef{GHC/Stg/Syntax.hs}{UpdateFlag} }} | r :: :: ReEntrant {{ com Function (re-entrant closure) }} | u :: :: Updatable {{ com Thunk (updatable closure) }} cl :: 'StgRhsClosure_' ::= {{ com StgRhsClosure }} | \ upd ccs xs . e :: :: StgRhsClosure -rhs :: 'StgRhs_' ::= {{ com Right-hand sides, \coderef{stgSyn/StgSyn.hs}{StgRhs} }} +rhs :: 'StgRhs_' ::= {{ com Right-hand sides, \coderef{GHC/Stg/Syntax.hs}{StgRhs} }} | cl :: :: StgRhsClosure {{ com Closure }} | K ccs args :: :: StgRhsCon {{ com Constructor }} | x :: :: StgRhsIndirection {{ com Indirection (runtime only) }} -alt :: 'StgAlt_' ::= {{ com Case alternative, \coderef{stgSyn/StgSyn.hs}{StgAlt} }} +alt :: 'StgAlt_' ::= {{ com Case alternative, \coderef{GHC/Stg/Syntax.hs}{StgAlt} }} | K -> e :: :: StgAlt {{ com Constructor applied to fresh names }} terminals :: 'terminals_' ::= ===================================== docs/stg-spec/stg-spec.mng ===================================== @@ -172,7 +172,7 @@ The implementations of \textsc{App} rules are spread across two different calling conventions for functions: slow calls and direct calls. Direct calls handle saturated and over-applied cases (\coderef{GHC/StgToCmm/Layout.hs}{slowArgs}), while slow -calls handle all cases (\textit{utils/genapply/GenApply.hs}); +calls handle all cases (\textit{utils/genapply/Main.hs}); in particular, these cases ensure that the current cost-center reverts to the one originally at the call site. \item The \textsc{App} rule demonstrates that modern GHC View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ffd7eef22f197ba44f0ced97ebc988f2d7d643a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ffd7eef22f197ba44f0ced97ebc988f2d7d643a4 You're receiving 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 23 03:10:40 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:10:40 -0400 Subject: [Git][ghc/ghc][master] 5 commits: Refactor the `MatchResult` type in the desugarer Message-ID: <5ea107301d0e1_616765c7a286610055@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 9 changed files: - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match.hs-boot - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Utils.hs Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -1014,26 +1014,26 @@ dsDo stmts go _ (ParStmt {}) _ = panic "dsDo ParStmt" go _ (TransStmt {}) _ = panic "dsDo TransStmt" -dsHandleMonadicFailure :: LPat GhcTc -> MatchResult -> FailOperator GhcTc -> DsM CoreExpr +dsHandleMonadicFailure :: LPat GhcTc -> MatchResult CoreExpr -> FailOperator GhcTc -> DsM CoreExpr -- In a do expression, pattern-match failure just calls -- the monadic 'fail' rather than throwing an exception -dsHandleMonadicFailure pat match m_fail_op - | matchCanFail match = do - fail_op <- case m_fail_op of - -- Note that (non-monadic) list comprehension, pattern guards, etc could - -- have fallible bindings without an explicit failure op, but this is - -- handled elsewhere. See Note [Failing pattern matches in Stmts] the - -- breakdown of regular and special binds. - Nothing -> pprPanic "missing fail op" $ - text "Pattern match:" <+> ppr pat <+> - text "is failable, and fail_expr was left unset" - Just fail_op -> pure fail_op - dflags <- getDynFlags - fail_msg <- mkStringExpr (mk_fail_msg dflags pat) - fail_expr <- dsSyntaxExpr fail_op [fail_msg] - extractMatchResult match fail_expr - | otherwise = - extractMatchResult match (error "It can't fail") +dsHandleMonadicFailure pat match m_fail_op = + case shareFailureHandler match of + MR_Infallible body -> body + MR_Fallible body -> do + fail_op <- case m_fail_op of + -- Note that (non-monadic) list comprehension, pattern guards, etc could + -- have fallible bindings without an explicit failure op, but this is + -- handled elsewhere. See Note [Failing pattern matches in Stmts] the + -- breakdown of regular and special binds. + Nothing -> pprPanic "missing fail op" $ + text "Pattern match:" <+> ppr pat <+> + text "is failable, and fail_expr was left unset" + Just fail_op -> pure fail_op + dflags <- getDynFlags + fail_msg <- mkStringExpr (mk_fail_msg dflags pat) + fail_expr <- dsSyntaxExpr fail_op [fail_msg] + body fail_expr mk_fail_msg :: DynFlags -> Located e -> String mk_fail_msg dflags pat = "Pattern match failure in do expression at " ++ ===================================== compiler/GHC/HsToCore/Expr.hs-boot ===================================== @@ -9,4 +9,4 @@ dsLExpr, dsLExprNoLP :: LHsExpr GhcTc -> DsM CoreExpr dsSyntaxExpr :: SyntaxExpr GhcTc -> [CoreExpr] -> DsM CoreExpr dsLocalBinds :: LHsLocalBinds GhcTc -> CoreExpr -> DsM CoreExpr -dsHandleMonadicFailure :: LPat GhcTc -> MatchResult -> FailOperator GhcTc -> DsM CoreExpr +dsHandleMonadicFailure :: LPat GhcTc -> MatchResult CoreExpr -> FailOperator GhcTc -> DsM CoreExpr ===================================== compiler/GHC/HsToCore/GuardedRHSs.hs ===================================== @@ -52,7 +52,7 @@ dsGuarded grhss rhs_ty mb_rhss_deltas = do error_expr <- mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID rhs_ty empty extractMatchResult match_result error_expr --- In contrast, @dsGRHSs@ produces a @MatchResult at . +-- In contrast, @dsGRHSs@ produces a @MatchResult CoreExpr at . dsGRHSs :: HsMatchContext GhcRn -> GRHSs GhcTc (LHsExpr GhcTc) -- ^ Guarded RHSs @@ -60,7 +60,7 @@ dsGRHSs :: HsMatchContext GhcRn -> Maybe (NonEmpty Deltas) -- ^ Refined pattern match checking -- models, one for each GRHS. Defaults -- to 'initDeltas' if 'Nothing'. - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) dsGRHSs hs_ctx (GRHSs _ grhss binds) rhs_ty mb_rhss_deltas = ASSERT( notNull grhss ) do { match_results <- case toList <$> mb_rhss_deltas of @@ -73,14 +73,14 @@ dsGRHSs hs_ctx (GRHSs _ grhss binds) rhs_ty mb_rhss_deltas ; return match_result2 } dsGRHS :: HsMatchContext GhcRn -> Type -> Deltas -> LGRHS GhcTc (LHsExpr GhcTc) - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) dsGRHS hs_ctx rhs_ty rhs_deltas (L _ (GRHS _ guards rhs)) = updPmDeltas rhs_deltas (matchGuards (map unLoc guards) (PatGuard hs_ctx) rhs rhs_ty) {- ************************************************************************ * * -* matchGuard : make a MatchResult from a guarded RHS * +* matchGuard : make a MatchResult CoreExpr CoreExpr from a guarded RHS * * * ************************************************************************ -} @@ -89,7 +89,7 @@ matchGuards :: [GuardStmt GhcTc] -- Guard -> HsStmtContext GhcRn -- Context -> LHsExpr GhcTc -- RHS -> Type -- Type of RHS of guard - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) -- See comments with HsExpr.Stmt re what a BodyStmt means -- Here we must be in a guard context (not do-expression, nor list-comp) @@ -130,7 +130,7 @@ matchGuards (BindStmt _ pat bind_rhs : stmts) ctx rhs rhs_ty = do core_rhs <- dsLExpr bind_rhs match_result' <- matchSinglePatVar match_var (StmtCtxt ctx) pat rhs_ty match_result - pure $ adjustMatchResult (bindNonRec match_var core_rhs) match_result' + pure $ bindNonRec match_var core_rhs <$> match_result' matchGuards (LastStmt {} : _) _ _ _ = panic "matchGuards LastStmt" matchGuards (ParStmt {} : _) _ _ _ = panic "matchGuards ParStmt" ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -174,7 +174,7 @@ type MatchId = Id -- See Note [Match Ids] match :: [MatchId] -- ^ Variables rep\'ing the exprs we\'re matching with. See Note [Match Ids] -> Type -- ^ Type of the case expression -> [EquationInfo] -- ^ Info about patterns, etc. (type synonym below) - -> DsM MatchResult -- ^ Desugared result! + -> DsM (MatchResult CoreExpr) -- ^ Desugared result! match [] ty eqns = ASSERT2( not (null eqns), ppr ty ) @@ -198,20 +198,21 @@ match (v:vs) ty eqns -- Eqns *can* be empty ; whenDOptM Opt_D_dump_view_pattern_commoning (debug grouped) ; match_results <- match_groups grouped - ; return (adjustMatchResult (foldr (.) id aux_binds) $ - foldr1 combineMatchResults match_results) } + ; return $ foldr (.) id aux_binds <$> + foldr1 combineMatchResults match_results + } where vars = v :| vs dropGroup :: Functor f => f (PatGroup,EquationInfo) -> f EquationInfo dropGroup = fmap snd - match_groups :: [NonEmpty (PatGroup,EquationInfo)] -> DsM (NonEmpty MatchResult) - -- Result list of [MatchResult] is always non-empty + match_groups :: [NonEmpty (PatGroup,EquationInfo)] -> DsM (NonEmpty (MatchResult CoreExpr)) + -- Result list of [MatchResult CoreExpr] is always non-empty match_groups [] = matchEmpty v ty match_groups (g:gs) = mapM match_group $ g :| gs - match_group :: NonEmpty (PatGroup,EquationInfo) -> DsM MatchResult + match_group :: NonEmpty (PatGroup,EquationInfo) -> DsM (MatchResult CoreExpr) match_group eqns@((group,_) :| _) = case group of PgCon {} -> matchConFamily vars ty (ne $ subGroupUniq [(c,e) | (PgCon c, e) <- eqns']) @@ -245,26 +246,26 @@ match (v:vs) ty eqns -- Eqns *can* be empty maybeWarn $ (map (\g -> text "Putting these view expressions into the same case:" <+> (ppr g)) (filter (not . null) gs)) -matchEmpty :: MatchId -> Type -> DsM (NonEmpty MatchResult) +matchEmpty :: MatchId -> Type -> DsM (NonEmpty (MatchResult CoreExpr)) -- See Note [Empty case expressions] matchEmpty var res_ty - = return [MatchResult CanFail mk_seq] + = return [MR_Fallible mk_seq] where mk_seq fail = return $ mkWildCase (Var var) (idType var) res_ty [(DEFAULT, [], fail)] -matchVariables :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchVariables :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) -- Real true variables, just like in matchVar, SLPJ p 94 -- No binding to do: they'll all be wildcards by now (done in tidy) matchVariables (_ :| vars) ty eqns = match vars ty $ NEL.toList $ shiftEqns eqns -matchBangs :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchBangs :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) matchBangs (var :| vars) ty eqns = do { match_result <- match (var:vars) ty $ NEL.toList $ decomposeFirstPat getBangPat <$> eqns ; return (mkEvalMatchResult var ty match_result) } -matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) = do { let CoPat _ co pat _ = firstPat eqn1 @@ -276,7 +277,7 @@ matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) ; let bind = NonRec var' (core_wrap (Var var)) ; return (mkCoLetMatchResult bind match_result) } -matchView :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchView :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) -- Apply the view function to the match variable and then match that matchView (var :| vars) ty (eqns@(eqn1 :| _)) = do { -- we could pass in the expr from the PgView, @@ -294,7 +295,7 @@ matchView (var :| vars) ty (eqns@(eqn1 :| _)) (mkCoreAppDs (text "matchView") viewExpr' (Var var)) match_result) } -matchOverloadedList :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchOverloadedList :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) matchOverloadedList (var :| vars) ty (eqns@(eqn1 :| _)) -- Since overloaded list patterns are treated as view patterns, -- the code is roughly the same as for matchView @@ -829,7 +830,7 @@ matchSimply scrut hs_ctx pat result_expr fail_expr = do extractMatchResult match_result' fail_expr matchSinglePat :: CoreExpr -> HsMatchContext GhcRn -> LPat GhcTc - -> Type -> MatchResult -> DsM MatchResult + -> Type -> MatchResult CoreExpr -> DsM (MatchResult CoreExpr) -- matchSinglePat ensures that the scrutinee is a variable -- and then calls matchSinglePatVar -- @@ -844,11 +845,12 @@ matchSinglePat (Var var) ctx pat ty match_result matchSinglePat scrut hs_ctx pat ty match_result = do { var <- selectSimpleMatchVarL pat ; match_result' <- matchSinglePatVar var hs_ctx pat ty match_result - ; return (adjustMatchResult (bindNonRec var scrut) match_result') } + ; return $ bindNonRec var scrut <$> match_result' + } matchSinglePatVar :: Id -- See Note [Match Ids] -> HsMatchContext GhcRn -> LPat GhcTc - -> Type -> MatchResult -> DsM MatchResult + -> Type -> MatchResult CoreExpr -> DsM (MatchResult CoreExpr) matchSinglePatVar var ctx pat ty match_result = ASSERT2( isInternalName (idName var), ppr var ) do { dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/Match.hs-boot ===================================== @@ -11,7 +11,7 @@ import GHC.Hs.Extension ( GhcRn, GhcTc ) match :: [Id] -> Type -> [EquationInfo] - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) matchWrapper :: HsMatchContext GhcRn @@ -32,5 +32,5 @@ matchSinglePatVar -> HsMatchContext GhcRn -> LPat GhcTc -> Type - -> MatchResult - -> DsM MatchResult + -> MatchResult CoreExpr + -> DsM (MatchResult CoreExpr) ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -27,6 +27,7 @@ import GHC.Types.Basic ( Origin(..) ) import GHC.Tc.Utils.TcType import GHC.HsToCore.Monad import GHC.HsToCore.Utils +import GHC.Core ( CoreExpr ) import GHC.Core.Make ( mkCoreLets ) import Util import GHC.Types.Id @@ -94,7 +95,7 @@ have-we-used-all-the-constructors? question; the local function matchConFamily :: NonEmpty Id -> Type -> NonEmpty (NonEmpty EquationInfo) - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) -- Each group of eqns is for a single constructor matchConFamily (var :| vars) ty groups = do alts <- mapM (fmap toRealAlt . matchOneConLike vars ty) groups @@ -107,7 +108,7 @@ matchConFamily (var :| vars) ty groups matchPatSyn :: NonEmpty Id -> Type -> NonEmpty EquationInfo - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) matchPatSyn (var :| vars) ty eqns = do alt <- fmap toSynAlt $ matchOneConLike vars ty eqns return (mkCoSynCaseMatchResult var ty alt) @@ -134,14 +135,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor -- and returns the types of the *value* args, which is what we want match_group :: [Id] - -> [(ConArgPats, EquationInfo)] -> DsM MatchResult + -> [(ConArgPats, EquationInfo)] -> DsM (MatchResult CoreExpr) -- All members of the group have compatible ConArgPats match_group arg_vars arg_eqn_prs = ASSERT( notNull arg_eqn_prs ) do { (wraps, eqns') <- liftM unzip (mapM shift arg_eqn_prs) ; let group_arg_vars = select_arg_vars arg_vars arg_eqn_prs ; match_result <- match (group_arg_vars ++ vars) ty eqns' - ; return (adjustMatchResult (foldr1 (.) wraps) match_result) } + ; return $ foldr1 (.) wraps <$> match_result + } shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, pat_binds = bind, pat_args = args ===================================== compiler/GHC/HsToCore/Match/Literal.hs ===================================== @@ -407,7 +407,7 @@ tidyNPat over_lit mb_neg eq outer_ty matchLiterals :: NonEmpty Id -> Type -- ^ Type of the whole case expression -> NonEmpty (NonEmpty EquationInfo) -- ^ All PgLits - -> DsM MatchResult + -> DsM (MatchResult CoreExpr) matchLiterals (var :| vars) ty sub_groups = do { -- Deal with each group @@ -424,7 +424,7 @@ matchLiterals (var :| vars) ty sub_groups return (mkCoPrimCaseMatchResult var ty $ NEL.toList alts) } where - match_group :: NonEmpty EquationInfo -> DsM (Literal, MatchResult) + match_group :: NonEmpty EquationInfo -> DsM (Literal, MatchResult CoreExpr) match_group eqns@(firstEqn :| _) = do { dflags <- getDynFlags ; let platform = targetPlatform dflags @@ -432,7 +432,7 @@ matchLiterals (var :| vars) ty sub_groups ; match_result <- match vars ty (NEL.toList $ shiftEqns eqns) ; return (hsLitKey platform hs_lit, match_result) } - wrap_str_guard :: Id -> (Literal,MatchResult) -> DsM MatchResult + wrap_str_guard :: Id -> (Literal,MatchResult CoreExpr) -> DsM (MatchResult CoreExpr) -- Equality check for string literals wrap_str_guard eq_str (LitString s, mr) = do { -- We now have to convert back to FastString. Perhaps there @@ -473,7 +473,7 @@ hsLitKey _ l = pprPanic "hsLitKey" (ppr l) ************************************************************************ -} -matchNPats :: NonEmpty Id -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchNPats :: NonEmpty Id -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) matchNPats (var :| vars) ty (eqn1 :| eqns) -- All for the same literal = do { let NPat _ (L _ lit) mb_neg eq_chk = firstPat eqn1 ; lit_expr <- dsOverLit lit @@ -502,7 +502,7 @@ We generate: \end{verbatim} -} -matchNPlusKPats :: NonEmpty Id -> Type -> NonEmpty EquationInfo -> DsM MatchResult +matchNPlusKPats :: NonEmpty Id -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) -- All NPlusKPats, for the *same* literal k matchNPlusKPats (var :| vars) ty (eqn1 :| eqns) = do { let NPlusKPat _ (L _ n1) (L _ lit1) lit2 ge minus @@ -515,7 +515,7 @@ matchNPlusKPats (var :| vars) ty (eqn1 :| eqns) ; match_result <- match vars ty eqns' ; return (mkGuardedMatchResult pred_expr $ mkCoLetMatchResult (NonRec n1 minusk_expr) $ - adjustMatchResult (foldr1 (.) wraps) $ + fmap (foldr1 (.) wraps) $ match_result) } where shift n1 eqn@(EqnInfo { eqn_pats = NPlusKPat _ (L _ n) _ _ _ _ : pats }) ===================================== compiler/GHC/HsToCore/Monad.hs ===================================== @@ -6,10 +6,14 @@ Monadery used in desugaring -} -{-# LANGUAGE FlexibleInstances, FlexibleContexts #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} -- instance MonadThings is necessarily an orphan +{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -fno-warn-orphans #-} -- instance MonadThings is necessarily an orphan + module GHC.HsToCore.Monad ( DsM, mapM, mapAndUnzipM, initDs, initDsTc, initTcDsForSolver, initDsWithModGuts, fixDs, @@ -42,8 +46,7 @@ module GHC.HsToCore.Monad ( -- Data types DsMatchContext(..), - EquationInfo(..), MatchResult(..), DsWrapper, idDsWrapper, - CanItFail(..), orFail, + EquationInfo(..), MatchResult (..), runMatchResult, DsWrapper, idDsWrapper, -- Levity polymorphism dsNoLevPoly, dsNoLevPolyExpr, dsWhenNoErrs, @@ -119,7 +122,7 @@ data EquationInfo -- @W# -1## :: Word@, but we shouldn't warn about an overflowed -- literal for /both/ of these cases. - , eqn_rhs :: MatchResult + , eqn_rhs :: MatchResult CoreExpr -- ^ What to do after match } @@ -130,25 +133,38 @@ type DsWrapper = CoreExpr -> CoreExpr idDsWrapper :: DsWrapper idDsWrapper e = e --- The semantics of (match vs (EqnInfo wrap pats rhs)) is the MatchResult +-- The semantics of (match vs (EqnInfo wrap pats rhs)) is the MatchResult CoreExpr -- \fail. wrap (case vs of { pats -> rhs fail }) -- where vs are not bound by wrap - --- A MatchResult is an expression with a hole in it -data MatchResult - = MatchResult - CanItFail -- Tells whether the failure expression is used - (CoreExpr -> DsM CoreExpr) - -- Takes a expression to plug in at the - -- failure point(s). The expression should - -- be duplicatable! - -data CanItFail = CanFail | CantFail - -orFail :: CanItFail -> CanItFail -> CanItFail -orFail CantFail CantFail = CantFail -orFail _ _ = CanFail +-- | This is a value of type a with potentially a CoreExpr-shaped hole in it. +-- This is used to deal with cases where we are potentially handling pattern +-- match failure, and want to later specify how failure is handled. +data MatchResult a + -- | We represent the case where there is no hole without a function from + -- 'CoreExpr', like this, because sometimes we have nothing to put in the + -- hole and so want to be sure there is in fact no hole. + = MR_Infallible (DsM a) + | MR_Fallible (CoreExpr -> DsM a) + deriving (Functor) + +-- | Product is an "or" on falliblity---the combined match result is infallible +-- only if the left and right argument match results both were. +-- +-- This is useful for combining a bunch of alternatives together and then +-- getting the overall falliblity of the entire group. See 'mkDataConCase' for +-- an example. +instance Applicative MatchResult where + pure v = MR_Infallible (pure v) + MR_Infallible f <*> MR_Infallible x = MR_Infallible (f <*> x) + f <*> x = MR_Fallible $ \fail -> runMatchResult fail f <*> runMatchResult fail x + +-- Given a fail expression to use, and a MatchResult CoreExpr, compute the filled CoreExpr whether +-- the MatchResult CoreExpr was failable or not. +runMatchResult :: CoreExpr -> MatchResult a -> DsM a +runMatchResult fail = \case + MR_Infallible body -> body + MR_Fallible body_fn -> body_fn fail {- ************************************************************************ ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -10,6 +10,7 @@ This module exports some utility functions of no great interest. {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -18,10 +19,11 @@ module GHC.HsToCore.Utils ( EquationInfo(..), firstPat, shiftEqns, - MatchResult(..), CanItFail(..), CaseAlt(..), + MatchResult (..), CaseAlt(..), cantFailMatchResult, alwaysFailMatchResult, extractMatchResult, combineMatchResults, - adjustMatchResult, adjustMatchResultDs, + adjustMatchResultDs, + shareFailureHandler, mkCoLetMatchResult, mkViewMatchResult, mkGuardedMatchResult, matchCanFail, mkEvalMatchResult, mkCoPrimCaseMatchResult, mkCoAlgCaseMatchResult, mkCoSynCaseMatchResult, @@ -85,6 +87,7 @@ import GHC.Tc.Types.Evidence import Control.Monad ( zipWithM ) import Data.List.NonEmpty (NonEmpty(..)) +import Data.Maybe (maybeToList) import qualified Data.List.NonEmpty as NEL {- @@ -192,48 +195,42 @@ shiftEqns :: Functor f => f EquationInfo -> f EquationInfo -- Drop the first pattern in each equation shiftEqns = fmap $ \eqn -> eqn { eqn_pats = tail (eqn_pats eqn) } --- Functions on MatchResults +-- Functions on MatchResult CoreExprs -matchCanFail :: MatchResult -> Bool -matchCanFail (MatchResult CanFail _) = True -matchCanFail (MatchResult CantFail _) = False +matchCanFail :: MatchResult a -> Bool +matchCanFail (MR_Fallible {}) = True +matchCanFail (MR_Infallible {}) = False -alwaysFailMatchResult :: MatchResult -alwaysFailMatchResult = MatchResult CanFail (\fail -> return fail) +alwaysFailMatchResult :: MatchResult CoreExpr +alwaysFailMatchResult = MR_Fallible $ \fail -> return fail -cantFailMatchResult :: CoreExpr -> MatchResult -cantFailMatchResult expr = MatchResult CantFail (\_ -> return expr) +cantFailMatchResult :: CoreExpr -> MatchResult CoreExpr +cantFailMatchResult expr = MR_Infallible $ return expr -extractMatchResult :: MatchResult -> CoreExpr -> DsM CoreExpr -extractMatchResult (MatchResult CantFail match_fn) _ - = match_fn (error "It can't fail!") +extractMatchResult :: MatchResult CoreExpr -> CoreExpr -> DsM CoreExpr +extractMatchResult match_result failure_expr = + runMatchResult + failure_expr + (shareFailureHandler match_result) -extractMatchResult (MatchResult CanFail match_fn) fail_expr = do - (fail_bind, if_it_fails) <- mkFailurePair fail_expr - body <- match_fn if_it_fails - return (mkCoreLet fail_bind body) - - -combineMatchResults :: MatchResult -> MatchResult -> MatchResult -combineMatchResults (MatchResult CanFail body_fn1) - (MatchResult can_it_fail2 body_fn2) - = MatchResult can_it_fail2 body_fn - where - body_fn fail = do body2 <- body_fn2 fail - (fail_bind, duplicatable_expr) <- mkFailurePair body2 - body1 <- body_fn1 duplicatable_expr - return (Let fail_bind body1) - -combineMatchResults match_result1@(MatchResult CantFail _) _ +combineMatchResults :: MatchResult CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr +combineMatchResults match_result1@(MR_Infallible _) _ = match_result1 - -adjustMatchResult :: DsWrapper -> MatchResult -> MatchResult -adjustMatchResult encl_fn (MatchResult can_it_fail body_fn) - = MatchResult can_it_fail (\fail -> encl_fn <$> body_fn fail) - -adjustMatchResultDs :: (CoreExpr -> DsM CoreExpr) -> MatchResult -> MatchResult -adjustMatchResultDs encl_fn (MatchResult can_it_fail body_fn) - = MatchResult can_it_fail (\fail -> encl_fn =<< body_fn fail) +combineMatchResults match_result1 match_result2 = + -- if the first pattern needs a failure handler (i.e. if it is is fallible), + -- make it let-bind it bind it with `shareFailureHandler`. + case shareFailureHandler match_result1 of + MR_Infallible _ -> match_result1 + MR_Fallible body_fn1 -> MR_Fallible $ \fail_expr -> + -- Before actually failing, try the next match arm. + body_fn1 =<< runMatchResult fail_expr match_result2 + +adjustMatchResultDs :: (a -> DsM b) -> MatchResult a -> MatchResult b +adjustMatchResultDs encl_fn = \case + MR_Infallible body_fn -> MR_Infallible $ + encl_fn =<< body_fn + MR_Fallible body_fn -> MR_Fallible $ \fail -> + encl_fn =<< body_fn fail wrapBinds :: [(Var,Var)] -> CoreExpr -> CoreExpr wrapBinds [] e = e @@ -247,51 +244,50 @@ wrapBind new old body -- NB: this function must deal with term seqVar :: Var -> CoreExpr -> CoreExpr seqVar var body = mkDefaultCase (Var var) var body -mkCoLetMatchResult :: CoreBind -> MatchResult -> MatchResult -mkCoLetMatchResult bind = adjustMatchResult (mkCoreLet bind) +mkCoLetMatchResult :: CoreBind -> MatchResult CoreExpr -> MatchResult CoreExpr +mkCoLetMatchResult bind = fmap (mkCoreLet bind) -- (mkViewMatchResult var' viewExpr mr) makes the expression -- let var' = viewExpr in mr -mkViewMatchResult :: Id -> CoreExpr -> MatchResult -> MatchResult -mkViewMatchResult var' viewExpr = - adjustMatchResult (mkCoreLet (NonRec var' viewExpr)) +mkViewMatchResult :: Id -> CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr +mkViewMatchResult var' viewExpr = fmap $ mkCoreLet $ NonRec var' viewExpr -mkEvalMatchResult :: Id -> Type -> MatchResult -> MatchResult -mkEvalMatchResult var ty - = adjustMatchResult (\e -> Case (Var var) var ty [(DEFAULT, [], e)]) +mkEvalMatchResult :: Id -> Type -> MatchResult CoreExpr -> MatchResult CoreExpr +mkEvalMatchResult var ty = fmap $ \e -> + Case (Var var) var ty [(DEFAULT, [], e)] -mkGuardedMatchResult :: CoreExpr -> MatchResult -> MatchResult -mkGuardedMatchResult pred_expr (MatchResult _ body_fn) - = MatchResult CanFail (\fail -> do body <- body_fn fail - return (mkIfThenElse pred_expr body fail)) +mkGuardedMatchResult :: CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr +mkGuardedMatchResult pred_expr mr = MR_Fallible $ \fail -> do + body <- runMatchResult fail mr + return (mkIfThenElse pred_expr body fail) mkCoPrimCaseMatchResult :: Id -- Scrutinee -> Type -- Type of the case - -> [(Literal, MatchResult)] -- Alternatives - -> MatchResult -- Literals are all unlifted + -> [(Literal, MatchResult CoreExpr)] -- Alternatives + -> MatchResult CoreExpr -- Literals are all unlifted mkCoPrimCaseMatchResult var ty match_alts - = MatchResult CanFail mk_case + = MR_Fallible mk_case where mk_case fail = do alts <- mapM (mk_alt fail) sorted_alts return (Case (Var var) var ty ((DEFAULT, [], fail) : alts)) sorted_alts = sortWith fst match_alts -- Right order for a Case - mk_alt fail (lit, MatchResult _ body_fn) + mk_alt fail (lit, mr) = ASSERT( not (litIsLifted lit) ) - do body <- body_fn fail + do body <- runMatchResult fail mr return (LitAlt lit, [], body) data CaseAlt a = MkCaseAlt{ alt_pat :: a, alt_bndrs :: [Var], alt_wrapper :: HsWrapper, - alt_result :: MatchResult } + alt_result :: MatchResult CoreExpr } mkCoAlgCaseMatchResult :: Id -- ^ Scrutinee -> Type -- ^ Type of exp -> NonEmpty (CaseAlt DataCon) -- ^ Alternatives (bndrs *include* tyvars, dicts) - -> MatchResult + -> MatchResult CoreExpr mkCoAlgCaseMatchResult var ty match_alts | isNewtype -- Newtype case; use a let = ASSERT( null match_alts_tail && null (tail arg_ids1) ) @@ -314,15 +310,14 @@ mkCoAlgCaseMatchResult var ty match_alts -- (not that splitTyConApp does, these days) newtype_rhs = unwrapNewTypeBody tc ty_args (Var var) -mkCoSynCaseMatchResult :: Id -> Type -> CaseAlt PatSyn -> MatchResult -mkCoSynCaseMatchResult var ty alt = MatchResult CanFail $ mkPatSynCase var ty alt +mkCoSynCaseMatchResult :: Id -> Type -> CaseAlt PatSyn -> MatchResult CoreExpr +mkCoSynCaseMatchResult var ty alt = MR_Fallible $ mkPatSynCase var ty alt mkPatSynCase :: Id -> Type -> CaseAlt PatSyn -> CoreExpr -> DsM CoreExpr mkPatSynCase var ty alt fail = do matcher <- dsLExpr $ mkLHsWrap wrapper $ nlHsTyApp matcher [getRuntimeRep ty, ty] - let MatchResult _ mkCont = match_result - cont <- mkCoreLams bndrs <$> mkCont fail + cont <- mkCoreLams bndrs <$> runMatchResult fail match_result return $ mkCoreAppsDs (text "patsyn" <+> ppr var) matcher [Var var, ensure_unstrict cont, Lam voidArgId fail] where MkCaseAlt{ alt_pat = psyn, @@ -336,49 +331,47 @@ mkPatSynCase var ty alt fail = do ensure_unstrict cont | needs_void_lam = Lam voidArgId cont | otherwise = cont -mkDataConCase :: Id -> Type -> NonEmpty (CaseAlt DataCon) -> MatchResult -mkDataConCase var ty alts@(alt1 :| _) = MatchResult fail_flag mk_case +mkDataConCase :: Id -> Type -> NonEmpty (CaseAlt DataCon) -> MatchResult CoreExpr +mkDataConCase var ty alts@(alt1 :| _) + = liftA2 mk_case mk_default mk_alts + -- The liftA2 combines the failability of all the alternatives and the default where con1 = alt_pat alt1 tycon = dataConTyCon con1 data_cons = tyConDataCons tycon - match_results = fmap alt_result alts - sorted_alts :: NonEmpty (CaseAlt DataCon) - sorted_alts = NEL.sortWith (dataConTag . alt_pat) alts + sorted_alts :: [ CaseAlt DataCon ] + sorted_alts = sortWith (dataConTag . alt_pat) $ NEL.toList alts var_ty = idType var (_, ty_args) = tcSplitTyConApp var_ty -- Don't look through newtypes -- (not that splitTyConApp does, these days) - mk_case :: CoreExpr -> DsM CoreExpr - mk_case fail = do - alts <- mapM (mk_alt fail) sorted_alts - return $ mkWildCase (Var var) (idType var) ty (mk_default fail ++ NEL.toList alts) - - mk_alt :: CoreExpr -> CaseAlt DataCon -> DsM CoreAlt - mk_alt fail MkCaseAlt{ alt_pat = con, - alt_bndrs = args, - alt_result = MatchResult _ body_fn } - = do { body <- body_fn fail - ; case dataConBoxer con of { - Nothing -> return (DataAlt con, args, body) ; - Just (DCB boxer) -> - do { us <- newUniqueSupply - ; let (rep_ids, binds) = initUs_ us (boxer ty_args args) - ; return (DataAlt con, rep_ids, mkLets binds body) } } } - - mk_default :: CoreExpr -> [CoreAlt] - mk_default fail | exhaustive_case = [] - | otherwise = [(DEFAULT, [], fail)] - - fail_flag :: CanItFail - fail_flag | exhaustive_case - = foldr orFail CantFail [can_it_fail | MatchResult can_it_fail _ <- NEL.toList match_results] - | otherwise - = CanFail - - mentioned_constructors = mkUniqSet $ map alt_pat $ NEL.toList alts + mk_case :: Maybe CoreAlt -> [CoreAlt] -> CoreExpr + mk_case def alts = mkWildCase (Var var) (idType var) ty $ + maybeToList def ++ alts + + mk_alts :: MatchResult [CoreAlt] + mk_alts = traverse mk_alt sorted_alts + + mk_alt :: CaseAlt DataCon -> MatchResult CoreAlt + mk_alt MkCaseAlt { alt_pat = con + , alt_bndrs = args + , alt_result = match_result } = + flip adjustMatchResultDs match_result $ \body -> do + case dataConBoxer con of + Nothing -> return (DataAlt con, args, body) + Just (DCB boxer) -> do + us <- newUniqueSupply + let (rep_ids, binds) = initUs_ us (boxer ty_args args) + return (DataAlt con, rep_ids, mkLets binds body) + + mk_default :: MatchResult (Maybe CoreAlt) + mk_default + | exhaustive_case = MR_Infallible $ return Nothing + | otherwise = MR_Fallible $ \fail -> return $ Just (DEFAULT, [], fail) + + mentioned_constructors = mkUniqSet $ map alt_pat sorted_alts un_mentioned_constructors = mkUniqSet data_cons `minusUniqSet` mentioned_constructors exhaustive_case = isEmptyUniqSet un_mentioned_constructors @@ -857,6 +850,18 @@ mkFailurePair expr where ty = exprType expr +-- Uses '@mkFailurePair@' to bind the failure case. Infallible matches have +-- neither a failure arg or failure "hole", so nothing is let-bound, and no +-- extraneous Core is produced. +shareFailureHandler :: MatchResult CoreExpr -> MatchResult CoreExpr +shareFailureHandler = \case + mr@(MR_Infallible _) -> mr + MR_Fallible match_fn -> MR_Fallible $ \fail_expr -> do + (fail_bind, shared_failure_handler) <- mkFailurePair fail_expr + body <- match_fn shared_failure_handler + -- Never unboxed, per the above, so always OK for `let` not `case`. + return $ Let fail_bind body + {- Note [Failure thunks and CPR] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ffd7eef22f197ba44f0ced97ebc988f2d7d643a4...401f7bb312aa6c570287d313f8b587aaebca72b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ffd7eef22f197ba44f0ced97ebc988f2d7d643a4...401f7bb312aa6c570287d313f8b587aaebca72b2 You're receiving 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 23 03:11:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:11:24 -0400 Subject: [Git][ghc/ghc][master] Mark DataCon wrappers CONLIKE Message-ID: <5ea1075caaa0d_6167f5265986614353@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 12 changed files: - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - libraries/parsec - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - + testsuite/tests/simplCore/should_run/T18012.hs - + testsuite/tests/simplCore/should_run/T18012.stdout - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/stranal/should_compile/T16029.stdout Changes: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -889,6 +889,10 @@ And now we have a known-constructor MkT that we can return. Notice that both (2) and (3) require exprIsConApp_maybe to gather and return a bunch of floats, both let and case bindings. +Note that this strategy introduces some subtle scenarios where a data-con +wrapper can be replaced by a data-con worker earlier than we’d like, see +Note [exprIsConApp_maybe for data-con wrappers: tricky corner]. + Note [beta-reduction in exprIsConApp_maybe] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The unfolding a definition (_e.g._ a let-bound variable or a datacon wrapper) is @@ -949,6 +953,60 @@ exprIsConApp_maybe does not return Just) then nothing happens, and nothing will happen the next time either. See test T16254, which checks the behavior of newtypes. + +Note [exprIsConApp_maybe for data-con wrappers: tricky corner] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Generally speaking + + * exprIsConApp_maybe honours the inline phase; that is, it does not look + inside the unfolding for an Id unless its unfolding is active in this phase. + That phase-sensitivity is expressed in the InScopeEnv (specifically, the + IdUnfoldingFun component of the InScopeEnv) passed to exprIsConApp_maybe. + + * Data-constructor wrappers are active only in phase 0 (the last phase); + see Note [Activation for data constructor wrappers] in GHC.Types.Id.Make. + +On the face of it that means that exprIsConApp_maybe won't look inside data +constructor wrappers until phase 0. But that seems pretty Bad. So we cheat. +For data con wrappers we unconditionally look inside its unfolding, regardless +of phase, so that we get case-of-known-constructor to fire in every phase. + +Perhaps unsurprisingly, this cheating can backfire. An example: + + data T = C !A B + foo p q = let x = C e1 e2 in seq x $ f x + {-# RULE "wurble" f (C a b) = b #-} + +In Core, the RHS of foo is + + let x = $WC e1 e2 in case x of y { C _ _ -> f x } + +and after doing a binder swap and inlining x, we have: + + case $WC e1 e2 of y { C _ _ -> f y } + +Case-of-known-constructor fires, but now we have to reconstruct a binding for +`y` (which was dead before the binder swap) on the RHS of the case alternative. +Naturally, we’ll use the worker: + + case e1 of a { DEFAULT -> let y = C a e2 in f y } + +and after inlining `y`, we have: + + case e1 of a { DEFAULT -> f (C a e2) } + +Now we might hope the "wurble" rule would fire, but alas, it will not: we have +replaced $WC with C, but the (desugared) rule matches on $WC! We weren’t +supposed to inline $WC yet for precisely that reason (see Note [Activation for +data constructor wrappers]), but our cheating in exprIsConApp_maybe came back to +bite us. + +This is rather unfortunate, especially since this can happen inside stable +unfoldings as well as ordinary code (which really happened, see !3041). But +there is no obvious solution except to delay case-of-known-constructor on +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 @@ -1033,7 +1091,8 @@ exprIsConApp_maybe (in_scope, id_unf) expr -- Look through data constructor wrappers: they inline late (See Note -- [Activation for data constructor wrappers]) but we want to do - -- case-of-known-constructor optimisation eagerly. + -- case-of-known-constructor optimisation eagerly (see Note + -- [exprIsConApp_maybe on data constructors with wrappers]). | isDataConWrapId fun , let rhs = uf_tmpl (realIdUnfolding fun) = go (Left in_scope) floats rhs cont ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -91,7 +91,7 @@ import GHC.Builtin.Types.Prim import FastString import Maybes import ListSetOps ( minusList ) -import GHC.Types.Basic ( Arity, isConLike ) +import GHC.Types.Basic ( Arity ) import Util import Pair import Data.ByteString ( ByteString ) @@ -1387,15 +1387,14 @@ isExpandableApp fn n_val_args | isWorkFreeApp fn n_val_args = True | otherwise = case idDetails fn of - DataConWorkId {} -> True -- Actually handled by isWorkFreeApp - RecSelId {} -> n_val_args == 1 -- See Note [Record selection] - ClassOpId {} -> n_val_args == 1 - PrimOpId {} -> False - _ | isBottomingId fn -> False + RecSelId {} -> n_val_args == 1 -- See Note [Record selection] + ClassOpId {} -> n_val_args == 1 + PrimOpId {} -> False + _ | isBottomingId fn -> False -- See Note [isExpandableApp: bottoming functions] - | isConLike (idRuleMatchInfo fn) -> True - | all_args_are_preds -> True - | otherwise -> False + | isConLikeId fn -> True + | all_args_are_preds -> True + | otherwise -> False where -- See if all the arguments are PredTys (implicit params or classes) ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -768,7 +768,7 @@ idRuleMatchInfo :: Id -> RuleMatchInfo idRuleMatchInfo id = inlinePragmaRuleMatchInfo (idInlinePragma id) isConLikeId :: Id -> Bool -isConLikeId id = isDataConWorkId id || isConLike (idRuleMatchInfo id) +isConLikeId id = isConLike (idRuleMatchInfo id) {- --------------------------------- ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -510,19 +510,21 @@ mkDataConWorkId wkr_name data_con alg_wkr_info = noCafIdInfo `setArityInfo` wkr_arity `setCprInfo` mkCprSig wkr_arity (dataConCPR data_con) + `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 `setLevityInfoWithType` wkr_ty -- NB: unboxed tuples have workers, so we can't use -- setNeverLevPoly + wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars 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` alwaysInlinePragma + `setInlinePragInfo` dataConWrapperInlinePragma `setUnfoldingInfo` newtype_unf `setLevityInfoWithType` wkr_ty id_arg1 = mkTemplateLocal 1 (head arg_tys) @@ -652,8 +654,8 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con mk_dmd str | isBanged str = evalDmd | otherwise = topDmd - wrap_prag = alwaysInlinePragma `setInlinePragmaActivation` - activeDuringFinal + wrap_prag = dataConWrapperInlinePragma + `setInlinePragmaActivation` activeDuringFinal -- See Note [Activation for data constructor wrappers] -- The wrapper will usually be inlined (see wrap_unf), so its @@ -763,6 +765,12 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con ; expr <- mk_rep_app prs (mkVarApps con_app rep_ids) ; return (unbox_fn expr) } + +dataConWrapperInlinePragma :: InlinePragma +-- See Note [DataCon wrappers are conlike] +dataConWrapperInlinePragma = alwaysInlinePragma { inl_rule = ConLike + , inl_inline = Inline } + {- Note [Activation for data constructor wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Activation on a data constructor wrapper allows it to inline only in Phase @@ -784,6 +792,37 @@ the order of type argument could make previously working RULEs fail. See also https://gitlab.haskell.org/ghc/ghc/issues/15840 . +Note [DataCon wrappers are conlike] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +DataCon workers are clearly ConLike --- they are the “Con” in +“ConLike”, after all --- but what about DataCon wrappers? Should they +be marked ConLike, too? + +Yes, absolutely! As described in Note [CONLIKE pragma] in +GHC.Types.Basic, isConLike influences GHC.Core.Utils.exprIsExpandable, +which is used by both RULE matching and the case-of-known-constructor +optimization. It’s crucial that both of those things can see +applications of DataCon wrappers: + + * User-defined RULEs match on wrappers, not workers, so we might + need to look through an unfolding built from a DataCon wrapper to + determine if a RULE matches. + + * Likewise, if we have something like + let x = $WC a b in ... case x of { C y z -> e } ... + we still want to apply case-of-known-constructor. + +Therefore, it’s important that we consider DataCon wrappers conlike. +This is especially true now that we don’t inline DataCon wrappers +until the final simplifier phase; see Note [Activation for data +constructor wrappers]. + +For further reading, see: + * Note [Conlike is interesting] in GHC.Core.Op.Simplify.Utils + * Note [Lone variables] in GHC.Core.Unfold + * Note [exprIsConApp_maybe on data constructors with wrappers] + in GHC.Core.SimpleOpt + * #18012 Note [Bangs on imported data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ee741870f028e036ab15ae6e2183f09b31e51ae2 +Subproject commit ce416997e15438ca616667995660e123ef7e219d ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 63, types: 43, coercions: 1, joins: 0/0} -- RHS size: {terms: 2, types: 4, coercions: 1, joins: 0/0} -T2431.$WRefl [InlPrag=INLINE[0]] :: forall a. a :~: a +T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, Cpr=m1, @@ -110,3 +110,6 @@ T2431.$tc'Refl $tc'Refl2 1# $krep3 + + + ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -120,11 +120,11 @@ Rule fired: mkRule @(_, ()) (T18013a) Rule fired: Class op fmap (BUILTIN) Rule fired: mkRule @((), _) (T18013a) Rule fired: Class op fmap (BUILTIN) -Rule fired: mkRule @(_, ()) (T18013a) +Rule fired: mkRule @((), _) (T18013a) Rule fired: Class op fmap (BUILTIN) Rule fired: mkRule @(_, ()) (T18013a) Rule fired: Class op fmap (BUILTIN) -Rule fired: mkRule @((), _) (T18013a) +Rule fired: mkRule @(_, ()) (T18013a) Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 106, types: 47, coercions: 0, joins: 0/0} -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} -T7360.$WFoo3 [InlPrag=INLINE[0]] :: Int -> Foo +T7360.$WFoo3 [InlPrag=INLINE[0] CONLIKE] :: Int -> Foo [GblId[DataConWrapper], Arity=1, Caf=NoCafRefs, ===================================== testsuite/tests/simplCore/should_run/T18012.hs ===================================== @@ -0,0 +1,41 @@ +module Main (main) where + +{- This program is designed to check that case-of-known-constructor +fires even if an application of a DataCon wrapper is floated out: + + * The early FloatOut pass will float `D False` out of `g`, since + it’s a constant, non-trivial expression. + + * But since `D` is strict, the floated-out expression will actually + be `$WD False`. + + * In simplifier phase 2, `f` will be inlined into `g`, leading to a + case expression that scrutinizes the floated-out binding. + + * If case-of-known-constructor fires, we’ll end up with `notRule + False`, the RULE will fire, and we get True. + + * If it doesn’t fire at phase 2, it will fire later at phase 0 when + we inline the DataCon wrapper. But now the RULE is inactive, so + we’ll end up with False instead. + +We want case-of-known-constructor to fire early, so we want the output +to be True. See #18012 for more details. -} + +main :: IO () +main = print (g ()) + +data T = D !Bool + +notRule :: Bool -> Bool +notRule x = x +{-# INLINE [0] notRule #-} +{-# RULES "notRule/False" [~0] notRule False = True #-} + +f :: T -> () -> Bool +f (D a) () = notRule a +{-# INLINE [100] f #-} -- so it isn’t inlined before FloatOut + +g :: () -> Bool +g x = f (D False) x +{-# NOINLINE g #-} ===================================== testsuite/tests/simplCore/should_run/T18012.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -93,3 +93,4 @@ test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) test('T17151', [], multimod_compile_and_run, ['T17151', '']) +test('T18012', normal, compile_and_run, ['']) ===================================== testsuite/tests/stranal/should_compile/T16029.stdout ===================================== @@ -1,4 +1,4 @@ -T16029.$WMkT [InlPrag=INLINE[0]] :: Int -> Int -> T +T16029.$WMkT [InlPrag=INLINE[0] CONLIKE] :: Int -> Int -> T Tmpl= \ (dt [Occ=Once!] :: Int) (dt [Occ=Once!] :: Int) -> = \ (dt [Occ=Once!] :: Int) (dt [Occ=Once!] :: Int) -> :: GHC.Prim.Int# -> GHC.Prim.Int# View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c9fae2342f19ab3e6ac688825a3817b23bf1fcc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c9fae2342f19ab3e6ac688825a3817b23bf1fcc You're receiving 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 23 03:12:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:12:01 -0400 Subject: [Git][ghc/ghc][master] Fix tab-completion for :break (#17989) Message-ID: <5ea10781d6bf1_6167865d29c661910@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 8 changed files: - ghc/GHCi/UI.hs - + testsuite/tests/ghci.debugger/scripts/T17989.script - + testsuite/tests/ghci.debugger/scripts/T17989.stdout - + testsuite/tests/ghci.debugger/scripts/T17989A.hs - + testsuite/tests/ghci.debugger/scripts/T17989B.hs - + testsuite/tests/ghci.debugger/scripts/T17989C.hs - + testsuite/tests/ghci.debugger/scripts/T17989M.hs - testsuite/tests/ghci.debugger/scripts/all.T Changes: ===================================== ghc/GHCi/UI.hs ===================================== @@ -48,7 +48,7 @@ import qualified GHC import GHC ( LoadHowMuch(..), Target(..), TargetId(..), InteractiveImport(..), TyThing(..), Phase, BreakIndex, Resume, SingleStep, Ghc, GetDocsFailure(..), - getModuleGraph, handleSourceError ) + getModuleGraph, handleSourceError, ms_mod ) import GHC.Driver.Main (hscParseDeclsWithLocation, hscParseStmtWithLocation) import GHC.Hs.ImpExp import GHC.Hs @@ -100,8 +100,8 @@ import qualified Data.ByteString.Char8 as BS import Data.Char import Data.Function import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef ) -import Data.List ( find, group, intercalate, intersperse, isPrefixOf, - isSuffixOf, nub, partition, sort, sortBy, (\\) ) +import Data.List ( elemIndices, find, group, intercalate, intersperse, + isPrefixOf, isSuffixOf, nub, partition, sort, sortBy, (\\) ) import qualified Data.Set as S import Data.Maybe import Data.Map (Map) @@ -173,7 +173,7 @@ ghciCommands = map mkCmd [ ("?", keepGoing help, noCompletion), ("add", keepGoingPaths addModule, completeFilename), ("abandon", keepGoing abandonCmd, noCompletion), - ("break", keepGoing breakCmd, completeIdentifier), + ("break", keepGoing breakCmd, completeBreakpoint), ("back", keepGoing backCmd, noCompletion), ("browse", keepGoing' (browseCmd False), completeModule), ("browse!", keepGoing' (browseCmd True), completeModule), @@ -3300,7 +3300,7 @@ completeCmd argLine0 = case parseLine argLine0 of completeGhciCommand, completeMacro, completeIdentifier, completeModule, completeSetModule, completeSeti, completeShowiOptions, completeHomeModule, completeSetOptions, completeShowOptions, - completeHomeModuleOrFile, completeExpression + completeHomeModuleOrFile, completeExpression, completeBreakpoint :: GhciMonad m => CompletionFunc m -- | Provide completions for last word in a given string. @@ -3356,6 +3356,68 @@ completeIdentifier line@(left, _) = dflags <- GHC.getSessionDynFlags return (filter (w `isPrefixOf`) (map (showPpr dflags) rdrs)) + +completeBreakpoint = wrapCompleter spaces $ \w -> do -- #17989 + -- See Note [Tab-completion for :break] + -- Pif ~ Pair with Identifier name and File name + pifsBreaks <- pifsFromModBreaks + pifsInscope <- pifsInscopeByPrefix w + pure $ [n | (n,f) <- pifsInscope, (unQual n, f) `elem` pifsBreaks] + where + -- Extract from the ModBreaks data all the names of top-level + -- functions eligible to set breakpoints, and put them + -- into a pair together with the filename where they are defined. + pifsFromModBreaks :: GhciMonad m => m [(String, FastString)] + pifsFromModBreaks = do + graph <- GHC.getModuleGraph + imods <- filterM GHC.moduleIsInterpreted $ + ms_mod <$> GHC.mgModSummaries graph + topDecls <- mapM pifsFromModBreaksByModule imods + pure $ concat topDecls + + -- Return all possible top-level pifs from the ModBreaks + -- for one module. + -- Identifiers of ModBreaks pifs are never qualified. + pifsFromModBreaksByModule :: GhciMonad m => Module -> m [(String, FastString)] + pifsFromModBreaksByModule mod = do + (_, locs, decls) <- getModBreak mod + let mbFile = safeHead $ mapMaybe srcSpanFileName_maybe $ elems locs + -- The first element in `decls` is the name of the top-level function. + let topLvlDecls = nub $ mapMaybe safeHead $ elems decls + pure $ case mbFile of + Nothing -> [] + (Just file) -> zip topLvlDecls $ repeat file + where + safeHead [] = Nothing + safeHead (h : _) = Just h + + -- Return the pifs of all identifieres (RdrNames) in scope, where + -- the identifier has the given prefix. + -- Identifiers of inscope pifs maybe qualified. + pifsInscopeByPrefix :: GhciMonad m => String -> m [(String, FastString)] + pifsInscopeByPrefix pref = do + dflags <- GHC.getSessionDynFlags + rdrs <- GHC.getRdrNamesInScope + let strnams = (filter (pref `isPrefixOf`) (map (showPpr dflags) rdrs)) + nams_fil <- mapM createInscopePif strnams + pure $ concat nams_fil + + -- Return a list of pifs for a single in scope identifier + createInscopePif :: GhciMonad m => String -> m [(String, FastString)] + createInscopePif str_rdr = do + names <- GHC.parseName str_rdr + let files = mapMaybe srcSpanFileName_maybe $ map nameSrcSpan names + pure $ zip (repeat str_rdr) files + + -- unQual "ModLev.Module.func" -> "func" + unQual :: String -> String + unQual qual_unqual = + let ixs = elemIndices '.' qual_unqual + in case ixs of + [] -> qual_unqual + _ -> drop (1 + last ixs) qual_unqual + + completeModule = wrapIdentCompleter $ \w -> do dflags <- GHC.getSessionDynFlags let pkg_mods = allVisibleModules dflags @@ -3437,6 +3499,41 @@ allVisibleModules dflags = listVisibleModuleNames dflags completeExpression = completeQuotedWord (Just '\\') "\"" listFiles completeIdentifier +{- +Note [Tab-completion for :break] +-------------------------------- +In tab-completion for the `:break` command, only those +identifiers should be shown, that are accepted in the +`:break` command. Hence these identifiers must be + +- defined in an interpreted module +- top-level +- currently in scope +- listed in a `ModBreaks` value as a possible breakpoint. + +The identifiers may be qualified or unqualified. + +To get all possible top-level breakpoints for tab-completeion +with the correct qualification do: + +1. Build the list called `pifsBreaks` of all pairs of +(Identifier, module-filename) from the `ModBreaks` values. +Here all identifiers are unqualified. + +2. Build the list called `pifInscope` of all pairs of +(Identifiers, module-filename) with identifiers from +the `GlobalRdrEnv`. Take only those identifiers that are +in scope and have the correct prefix. +Here the identifiers may be qualified. + +3. From the `pifInscope` list seclect all pairs that can be +found in the `pifsBreaks` list, by comparing only the +unqualified part of the identifier. +The remaining identifiers can be used for tab-completion. + +This ensures, that we show only identifiers, that can be used +in a `:break` command. +-} -- ----------------------------------------------------------------------------- -- commands for debugger @@ -3703,7 +3800,7 @@ findBreakAndSet :: GhciMonad m => Module -> (TickArray -> [(Int, RealSrcSpan)]) -> m () findBreakAndSet md lookupTickTree = do tickArray <- getTickArray md - (breakArray, _) <- getModBreak md + (breakArray, _, _) <- getModBreak md case lookupTickTree tickArray of [] -> liftIO $ putStrLn $ "No breakpoints found at that location." some -> mapM_ (breakAt breakArray) some @@ -3962,7 +4059,7 @@ getTickArray modl = do case lookupModuleEnv arrmap modl of Just arr -> return arr Nothing -> do - (_breakArray, ticks) <- getModBreak modl + (_breakArray, ticks, _) <- getModBreak modl let arr = mkTickArray (assocs ticks) setGHCiState st{tickarrays = extendModuleEnv arrmap modl arr} return arr @@ -4001,19 +4098,20 @@ turnBreakOnOff :: GHC.GhcMonad m => Bool -> BreakLocation -> m BreakLocation turnBreakOnOff onOff loc | onOff == breakEnabled loc = return loc | otherwise = do - (arr, _) <- getModBreak (breakModule loc) + (arr, _, _) <- getModBreak (breakModule loc) hsc_env <- GHC.getSession liftIO $ enableBreakpoint hsc_env arr (breakTick loc) onOff return loc { breakEnabled = onOff } getModBreak :: GHC.GhcMonad m - => Module -> m (ForeignRef BreakArray, Array Int SrcSpan) + => Module -> m (ForeignRef BreakArray, Array Int SrcSpan, Array Int [String]) getModBreak m = do mod_info <- fromMaybe (panic "getModBreak") <$> GHC.getModuleInfo m let modBreaks = GHC.modInfoModBreaks mod_info let arr = GHC.modBreaks_flags modBreaks let ticks = GHC.modBreaks_locs modBreaks - return (arr, ticks) + let decls = GHC.modBreaks_decls modBreaks + return (arr, ticks, decls) setBreakFlag :: GHC.GhcMonad m => Bool -> ForeignRef BreakArray -> Int -> m () setBreakFlag toggle arr i = do ===================================== testsuite/tests/ghci.debugger/scripts/T17989.script ===================================== @@ -0,0 +1,12 @@ +:l T17989M +:complete repl ":break " +-- all listed names are really breakpoints +:break B.bar +:break B.foo +:break T17989A.bar +:break T17989A.foo +:break T17989C.foo +:break foo +:break main +:complete repl ":break B." +:complete repl ":break f" ===================================== testsuite/tests/ghci.debugger/scripts/T17989.stdout ===================================== @@ -0,0 +1,20 @@ +7 7 ":break " +"B.bar" +"B.foo" +"T17989A.bar" +"T17989A.foo" +"T17989C.foo" +"foo" +"main" +Breakpoint 0 activated at T17989B.hs:10:9-25 +Breakpoint 1 activated at T17989B.hs:7:6-11 +Breakpoint 2 activated at T17989A.hs:10:7-13 +Breakpoint 3 activated at T17989A.hs:4:9-14 +Breakpoint 4 activated at T17989C.hs:4:9-26 +Breakpoint 4 was already set at T17989C.hs:4:9-26 +Breakpoint 5 activated at T17989M.hs:6:8-51 +2 2 ":break " +"B.bar" +"B.foo" +1 1 ":break " +"foo" ===================================== testsuite/tests/ghci.debugger/scripts/T17989A.hs ===================================== @@ -0,0 +1,13 @@ +module T17989A (foo, bar) where + +foo :: Int -> String +foo n = x <> y + where + x = "A.foo-" + y = priv n + +bar :: String +bar = "A.bar" + +priv :: Int -> String +priv n = "A.foo-" <> show n ===================================== testsuite/tests/ghci.debugger/scripts/T17989B.hs ===================================== @@ -0,0 +1,13 @@ +module T17989B (foo, bar) where + +foo :: Int -> String +foo n = + let x = "B.foo-" + y = priv n + in x <> y + +bar :: Int -> String +bar n = "B.bar" <> show n + +priv :: Int -> String +priv n = "B.foo-" <> show n ===================================== testsuite/tests/ghci.debugger/scripts/T17989C.hs ===================================== @@ -0,0 +1,7 @@ +module T17989C (foo) where + +foo :: Int -> String +foo n = "C.foo-" <> priv n + +priv :: Int -> String +priv n = "C.foo-" <> show n ===================================== testsuite/tests/ghci.debugger/scripts/T17989M.hs ===================================== @@ -0,0 +1,6 @@ +import qualified T17989A +import qualified T17989B as B +import T17989C + +main :: IO () +main = putStrLn (T17989A.foo 3 <> B.foo 5 <> foo 7) ===================================== testsuite/tests/ghci.debugger/scripts/all.T ===================================== @@ -125,3 +125,4 @@ test('T16700', normal, ghci_script, ['T16700.script']) test('break029', extra_files(['break029.hs']), ghci_script, ['break029.script']) test('T2215', normal, ghci_script, ['T2215.script']) +test('T17989', normal, ghci_script, ['T17989.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/48b8951e819e5d7d06ad7e168323de320d87bbd6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/48b8951e819e5d7d06ad7e168323de320d87bbd6 You're receiving 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 23 03:13:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:13:15 -0400 Subject: [Git][ghc/ghc][master] Do eager instantation in terms Message-ID: <5ea107cb9434c_6167e4e49b46626748@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 30 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Instantiate.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Zonk.hs - docs/users_guide/8.12.1-notes.rst - libraries/base/tests/T9681.stderr - testsuite/tests/ado/T13242a.stderr - testsuite/tests/ado/ado002.stderr - testsuite/tests/annotations/should_fail/annfail08.stderr - testsuite/tests/driver/T2182.stderr - testsuite/tests/gadt/gadt13.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ffde234854f49dba9ec4735aad74b30fd2deee29 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ffde234854f49dba9ec4735aad74b30fd2deee29 You're receiving 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 23 03:12:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:12:42 -0400 Subject: [Git][ghc/ghc][master] PPC NCG: Add DWARF constants and debug labels Message-ID: <5ea107aa7e58f_6167865d29c6623669@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - 10 changed files: - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - testsuite/tests/codeGen/should_compile/all.T - testsuite/tests/driver/T17586/all.T - testsuite/tests/rts/all.T - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/Dwarf/Constants.hs ===================================== @@ -12,6 +12,7 @@ import Outputable import GHC.Platform.Reg import GHC.CmmToAsm.X86.Regs +import GHC.CmmToAsm.PPC.Regs (toRegNo) import Data.Word @@ -215,6 +216,7 @@ dwarfRegNo p r = case platformArch p of | r == xmm13 -> 30 | r == xmm14 -> 31 | r == xmm15 -> 32 + ArchPPC_64 _ -> fromIntegral $ toRegNo r _other -> error "dwarfRegNo: Unsupported platform or unknown register!" -- | Virtual register number to use for return address. @@ -226,4 +228,5 @@ dwarfReturnRegNo p = case platformArch p of ArchX86 -> 8 -- eip ArchX86_64 -> 16 -- rip + ArchPPC_64 ELF_V2 -> 65 -- lr (link register) _other -> error "dwarfReturnRegNo: Unsupported platform!" ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -30,10 +30,13 @@ import GHC.CmmToAsm.PPC.Instr import GHC.CmmToAsm.PPC.Cond import GHC.CmmToAsm.PPC.Regs import GHC.CmmToAsm.CPrim +import GHC.Cmm.DebugBlock + ( DebugBlock(..) ) import GHC.CmmToAsm.Monad ( NatM, getNewRegNat, getNewLabelNat , getBlockIdNat, getPicBaseNat, getNewRegPairNat , getPicBaseMaybeNat, getPlatform, getConfig + , getDebugBlock, getFileId ) import GHC.CmmToAsm.Instr import GHC.CmmToAsm.PIC @@ -53,6 +56,8 @@ import GHC.Cmm.Switch import GHC.Cmm.CLabel import GHC.Cmm.Dataflow.Block import GHC.Cmm.Dataflow.Graph +import GHC.Core ( Tickish(..) ) +import GHC.Types.SrcLoc ( srcSpanFile, srcSpanStartLine, srcSpanStartCol ) -- The rest: import OrdList @@ -123,9 +128,17 @@ basicBlockCodeGen block = do let (_, nodes, tail) = blockSplit block id = entryLabel block stmts = blockToList nodes + -- Generate location directive + dbg <- getDebugBlock (entryLabel block) + loc_instrs <- case dblSourceTick =<< dbg of + Just (SourceNote span name) + -> do fileid <- getFileId (srcSpanFile span) + let line = srcSpanStartLine span; col =srcSpanStartCol span + return $ unitOL $ LOCATION fileid line col name + _ -> return nilOL mid_instrs <- stmtsToInstrs stmts tail_instrs <- stmtToInstrs tail - let instrs = mid_instrs `appOL` tail_instrs + let instrs = loc_instrs `appOL` mid_instrs `appOL` tail_instrs -- code generation may introduce new basic block boundaries, which -- are indicated by the NEWBLOCK instruction. We must split up the -- instruction stream into basic blocks again. Also, we extract ===================================== compiler/GHC/CmmToAsm/PPC/Instr.hs ===================================== @@ -187,6 +187,9 @@ data Instr -- comment pseudo-op = COMMENT FastString + -- location pseudo-op (file, line, col, name) + | LOCATION Int Int Int String + -- some static data spat out during code -- generation. Will be extracted before -- pretty-printing. @@ -643,6 +646,7 @@ ppc_isMetaInstr ppc_isMetaInstr instr = case instr of COMMENT{} -> True + LOCATION{} -> True LDATA{} -> True NEWBLOCK{} -> True DELTA{} -> True ===================================== compiler/GHC/CmmToAsm/PPC/Ppr.hs ===================================== @@ -59,14 +59,17 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = ArchPPC_64 ELF_V2 -> pprFunctionPrologue lbl _ -> pprLabel platform lbl) $$ -- blocks guaranteed not null, -- so label needed - vcat (map (pprBasicBlock platform top_info) blocks) + vcat (map (pprBasicBlock config top_info) blocks) $$ + (if ncgDebugLevel config > 0 + then ppr (mkAsmTempEndLabel lbl) <> char ':' else empty) $$ + pprSizeDecl platform lbl Just (CmmStaticsRaw info_lbl _) -> pprSectionAlign config (Section Text info_lbl) $$ (if platformHasSubsectionsViaSymbols platform then ppr (mkDeadStripPreventer info_lbl) <> char ':' else empty) $$ - vcat (map (pprBasicBlock platform top_info) blocks) $$ + vcat (map (pprBasicBlock config top_info) blocks) $$ -- above: Even the first block gets a label, because with branch-chain -- elimination, it might be the target of a goto. (if platformHasSubsectionsViaSymbols platform @@ -76,7 +79,15 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = <+> ppr info_lbl <+> char '-' <+> ppr (mkDeadStripPreventer info_lbl) - else empty) + else empty) $$ + pprSizeDecl platform info_lbl + +-- | Output the ELF .size directive. +pprSizeDecl :: Platform -> CLabel -> SDoc +pprSizeDecl platform lbl + = if osElfTarget (platformOS platform) + then text "\t.size" <+> ppr lbl <> text ", .-" <> ppr lbl + else empty pprFunctionDescriptor :: CLabel -> SDoc pprFunctionDescriptor lab = pprGloblDecl lab @@ -105,12 +116,19 @@ pprFunctionPrologue lab = pprGloblDecl lab $$ text "\t.localentry\t" <> ppr lab <> text ",.-" <> ppr lab -pprBasicBlock :: Platform -> LabelMap RawCmmStatics -> NatBasicBlock Instr -> SDoc -pprBasicBlock platform info_env (BasicBlock blockid instrs) +pprBasicBlock :: NCGConfig -> LabelMap RawCmmStatics -> NatBasicBlock Instr + -> SDoc +pprBasicBlock config info_env (BasicBlock blockid instrs) = maybe_infotable $$ - pprLabel platform (blockLbl blockid) $$ - vcat (map (pprInstr platform) instrs) + pprLabel platform asmLbl $$ + vcat (map (pprInstr platform) instrs) $$ + (if ncgDebugLevel config > 0 + then ppr (mkAsmTempEndLabel asmLbl) <> char ':' + else empty + ) where + asmLbl = blockLbl blockid + platform = ncgPlatform config maybe_infotable = case mapLookup blockid info_env of Nothing -> empty Just (CmmStaticsRaw info_lbl info) -> @@ -338,6 +356,9 @@ pprInstr platform instr = case instr of -- then text "# " <> ftext s -- else text "; " <> ftext s + LOCATION file line col _name + -> text "\t.loc" <+> ppr file <+> ppr line <+> ppr col + DELTA d -> pprInstr platform (COMMENT (mkFastString ("\tdelta = " ++ show d))) ===================================== compiler/GHC/CmmToAsm/PPC/Regs.hs ===================================== @@ -31,6 +31,7 @@ module GHC.CmmToAsm.PPC.Regs ( allMachRegNos, classOfRealReg, showReg, + toRegNo, -- machine specific allFPArgRegs, @@ -250,7 +251,9 @@ showReg n | n >= 32 && n <= 63 = "%f" ++ show (n - 32) | otherwise = "%unknown_powerpc_real_reg_" ++ show n - +toRegNo :: Reg -> RegNo +toRegNo (RegReal (RealRegSingle n)) = n +toRegNo _ = panic "PPC.toRegNo: unsupported register" -- machine specific ------------------------------------------------------------ ===================================== testsuite/tests/codeGen/should_compile/all.T ===================================== @@ -25,19 +25,14 @@ test('T9155', normal, compile, ['-O2']) test('T9303', normal, compile, ['-O2']) test('T9329', [when(unregisterised(), expect_broken(15467)), cmm_src], compile, ['']) -test('debug', - [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261))], - makefile_test, []) +test('debug', normal, makefile_test, []) test('T9964', normal, compile, ['-O']) test('T10518', [cmm_src], compile, ['']) -test('T10667', [ when((arch('powerpc64') or arch('powerpc64le')), - expect_broken(11261))], - compile, ['-g']) +test('T10667', normal, compile, ['-g']) test('T12115', normal, compile, ['']) test('T12355', normal, compile, ['']) test('T14999', - [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261)), - when(unregisterised(), skip), + [when(unregisterised(), skip), unless(opsys('linux') and arch('x86_64') and have_gdb() and have_readelf(), skip)], makefile_test, []) ===================================== testsuite/tests/driver/T17586/all.T ===================================== @@ -1,3 +1 @@ -test('T17586', - [when(arch('powerpc64') or arch('powerpc64le'), expect_broken(11261))], - makefile_test, []) +test('T17586', normal, makefile_test, []) ===================================== testsuite/tests/rts/all.T ===================================== @@ -385,10 +385,10 @@ test('keep-cafs-fail', [ extra_files(['KeepCafsBase.hs', 'KeepCafs1.hs', 'KeepCafs2.hs', 'KeepCafsMain.hs']), when(opsys('mingw32'), expect_broken (5987)), - when(platform('powerpc64le-unknown-linux'), expect_broken(11261)), when(opsys('freebsd'), expect_broken(16035)), filter_stdout_lines('Evaluated a CAF|exit.*'), ignore_stderr, # on OS X the shell emits an "Abort trap" message to stderr + req_rts_linker, ], makefile_test, ['KeepCafsFail']) @@ -397,7 +397,6 @@ test('keep-cafs', [ extra_files(['KeepCafsBase.hs', 'KeepCafs1.hs', 'KeepCafs2.hs', 'KeepCafsMain.hs']), when(opsys('mingw32'), expect_broken (5987)), - when(platform('powerpc64le-unknown-linux'), expect_broken(11261)), when(opsys('freebsd'), expect_broken(16035)), req_rts_linker ], ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -244,21 +244,11 @@ test('T13468', normal, makefile_test, ['T13468']) test('T13543', only_ways(['optasm']), compile, ['-ddump-str-signatures -ddump-cpr-signatures']) -test('T11272', - normal, - makefile_test, ['T11272']) -test('T12600', - normal, - makefile_test, ['T12600']) -test('T13658', - [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261))], - compile, ['-dcore-lint']) -test('T14779a', - [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261))], - compile, ['-dcore-lint']) -test('T14779b', - [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261))], - compile, ['-dcore-lint']) +test('T11272', normal, makefile_test, ['T11272']) +test('T12600', normal, makefile_test, ['T12600']) +test('T13658', normal, compile, ['-dcore-lint']) +test('T14779a', normal, compile, ['-dcore-lint']) +test('T14779b', normal, compile, ['-dcore-lint']) test('T13708', normal, compile, ['']) # thunk should inline here, so check whether or not it appears in the Core ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -81,10 +81,8 @@ test('T13429_2', normal, compile_and_run, ['']) test('T13750', normal, compile_and_run, ['']) test('T14178', normal, compile_and_run, ['']) test('T14768', reqlib('vector'), compile_and_run, ['']) -test('T14868', - [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261))], - compile_and_run, ['']) -test('T14894', [when((arch('powerpc64') or arch('powerpc64le')), expect_broken(11261))], compile_and_run, ['']) +test('T14868', normal, compile_and_run, ['']) +test('T14894', normal, compile_and_run, ['']) test('T14965', normal, compile_and_run, ['']) test('T15114', only_ways(['optasm']), compile_and_run, ['']) test('T15436', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/34a45ee600d5346f5d1728047fa185698ed7ee84 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/34a45ee600d5346f5d1728047fa185698ed7ee84 You're receiving 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 23 03:13:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:13:52 -0400 Subject: [Git][ghc/ghc][master] rts: Ensure that sigaction structs are initialized Message-ID: <5ea107f0eafe1_61673f81ef22dee46629328@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - 1 changed file: - rts/posix/Signals.c Changes: ===================================== rts/posix/Signals.c ===================================== @@ -624,7 +624,7 @@ set_sigtstp_action (bool handle) void install_vtalrm_handler(int sig, TickProc handle_tick) { - struct sigaction action; + struct sigaction action = {}; action.sa_handler = handle_tick; @@ -666,7 +666,8 @@ install_vtalrm_handler(int sig, TickProc handle_tick) void initDefaultHandlers(void) { - struct sigaction action,oact; + struct sigaction action = {}; + struct sigaction oact = {}; // install the SIGINT handler action.sa_handler = shutdown_handler; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6f84aca31290afc11acde0f86969a535e519e1d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6f84aca31290afc11acde0f86969a535e519e1d5 You're receiving 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 23 03:14:30 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:14:30 -0400 Subject: [Git][ghc/ghc][master] Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". Message-ID: <5ea108167293a_616776d1c7466319b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 2 changed files: - compiler/GHC/Driver/Session.hs - docs/users_guide/debugging.rst Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2658,6 +2658,8 @@ dynamic_flags_deps = [ (setDumpFlag Opt_D_dump_cmm_info) , make_ord_flag defGhcFlag "ddump-cmm-cps" (setDumpFlag Opt_D_dump_cmm_cps) + , make_ord_flag defGhcFlag "ddump-cmm-opt" + (setDumpFlag Opt_D_dump_opt_cmm) , make_ord_flag defGhcFlag "ddump-cfg-weights" (setDumpFlag Opt_D_dump_cfg_weights) , make_ord_flag defGhcFlag "ddump-core-stats" @@ -2766,7 +2768,7 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "ddump-rn-stats" (setDumpFlag Opt_D_dump_rn_stats) - , make_ord_flag defGhcFlag "ddump-opt-cmm" + , make_ord_flag defGhcFlag "ddump-opt-cmm" --old alias for cmm-opt (setDumpFlag Opt_D_dump_opt_cmm) , make_ord_flag defGhcFlag "ddump-simpl-stats" (setDumpFlag Opt_D_dump_simpl_stats) ===================================== docs/users_guide/debugging.rst ===================================== @@ -546,12 +546,18 @@ These flags dump various stages of the :ref:`native code generator's ` pipeline, which starts with C-\\- and produces native assembler. -.. ghc-flag:: -ddump-opt-cmm +.. ghc-flag:: -ddump-cmm-opt :shortdesc: Dump the results of C-\\- to C-\\- optimising passes :type: dynamic Dump the results of C-\\- to C-\\- optimising passes performed by the NCG. +.. ghc-flag:: -ddump-opt-cmm + :shortdesc: Dump the results of C-\\- to C-\\- optimising passes + :type: dynamic + + Alias for :ghc-flag:`-ddump-cmm-opt` + .. ghc-flag:: -ddump-asm-native :shortdesc: Dump initial assembly :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c29f0fa6ee831ec8a223561312d7176ef87a7ece -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c29f0fa6ee831ec8a223561312d7176ef87a7ece You're receiving 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 23 03:15:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:15:08 -0400 Subject: [Git][ghc/ghc][master] llvmGen: Remove -fast-llvm flag Message-ID: <5ea1083c1bb96_61673f8199536d9466349b0@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 3 changed files: - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/expected-undocumented-flags.txt Changes: ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -866,20 +866,6 @@ getOutputFilename stop_phase output basename dflags next_phase maybe_location | otherwise = persistent --- | The fast LLVM Pipeline skips the mangler and assembler, --- emitting object code directly from llc. --- --- slow: opt -> llc -> .s -> mangler -> as -> .o --- fast: opt -> llc -> .o --- --- hidden flag: -ffast-llvm --- --- if keep-s-files is specified, we need to go through --- the slow pipeline (Kavon Farvardin requested this). -fastLlvmPipeline :: DynFlags -> Bool -fastLlvmPipeline dflags - = not (gopt Opt_KeepSFiles dflags) && gopt Opt_FastLlvm dflags - -- | LLVM Options. These are flags to be passed to opt and llc, to ensure -- consistency we list them in pairs, so that they form groups. llvmOptions :: DynFlags @@ -890,7 +876,6 @@ llvmOptions dflags = ,"-relocation-model=" ++ rmodel) | not (null rmodel)] ++ [("-stack-alignment=" ++ (show align) ,"-stack-alignment=" ++ (show align)) | align > 0 ] - ++ [("", "-filetype=obj") | fastLlvmPipeline dflags ] -- Additional llc flags ++ [("", "-mcpu=" ++ mcpu) | not (null mcpu) @@ -1472,8 +1457,7 @@ runPhase (RealPhase LlvmOpt) input_fn dflags runPhase (RealPhase LlvmLlc) input_fn dflags = do - next_phase <- if | fastLlvmPipeline dflags -> maybeMergeForeign - -- hidden debugging flag '-dno-llvm-mangler' to skip mangling + next_phase <- if -- hidden debugging flag '-dno-llvm-mangler' to skip mangling | gopt Opt_NoLlvmMangler dflags -> return (As False) | otherwise -> return LlvmMangle ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2818,8 +2818,6 @@ dynamic_flags_deps = [ (NoArg (setGeneralFlag Opt_D_faststring_stats)) , make_ord_flag defGhcFlag "dno-llvm-mangler" (NoArg (setGeneralFlag Opt_NoLlvmMangler)) -- hidden flag - , make_ord_flag defGhcFlag "fast-llvm" - (NoArg (setGeneralFlag Opt_FastLlvm)) -- hidden flag , make_ord_flag defGhcFlag "dno-typeable-binds" (NoArg (setGeneralFlag Opt_NoTypeableBinds)) , make_ord_flag defGhcFlag "ddump-debug" ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -78,7 +78,6 @@ -fallow-overlapping-instances -fallow-undecidable-instances -farrows --fast-llvm -fbang-patterns -fbuilding-cabal-package -fconstraint-solver-iterations View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b4a8b60a5b403e02117ab0a30a386664845586b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b4a8b60a5b403e02117ab0a30a386664845586b You're receiving 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 23 03:15:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:15:43 -0400 Subject: [Git][ghc/ghc][master] Fix build warning; add more informative information to the linker; fix linker for empty sections Message-ID: <5ea1085f504ab_61673f81afeb5fbc66373a7@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - 2 changed files: - rts/linker/MachO.c - rts/posix/GetTime.c Changes: ===================================== rts/linker/MachO.c ===================================== @@ -677,6 +677,14 @@ static int relocateSection(ObjectCode* oc, int curSection) { Section * sect = &oc->sections[curSection]; + + IF_DEBUG(linker, debugBelch("relocateSection %d, info: %x\n", curSection, sect->info)); + + // empty sections (without segments), won't have their info filled. + // there is no relocation to be done for them. + if(sect->info == NULL) + return 1; + MachOSection * msect = sect->info->macho_section; // for access convenience MachORelocationInfo * relocs = sect->info->relocation_info; MachOSymbol * symbols = oc->info->macho_symbols; @@ -1192,7 +1200,7 @@ ocGetNames_MachO(ObjectCode* oc) SymbolAddr* commonStorage = NULL; unsigned long commonCounter; - IF_DEBUG(linker,debugBelch("ocGetNames_MachO: start\n")); + IF_DEBUG(linker,debugBelch("ocGetNames_MachO: %s start\n", OC_INFORMATIVE_FILENAME(oc))); Section *secArray; secArray = (Section*)stgCallocBytes( @@ -1449,7 +1457,7 @@ ocMprotect_MachO( ObjectCode *oc ) int ocResolve_MachO(ObjectCode* oc) { - IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n")); + IF_DEBUG(linker, debugBelch("ocResolve_MachO: %s start\n", OC_INFORMATIVE_FILENAME(oc))); if(NULL != oc->info->dsymCmd) { @@ -1460,6 +1468,9 @@ ocResolve_MachO(ObjectCode* oc) for (int i = 0; i < oc->n_sections; i++) { const char * sectionName = oc->info->macho_sections[i].sectname; + + IF_DEBUG(linker, debugBelch("ocResolve_MachO: section %d/%d: %s\n", i, oc->n_sections, sectionName)); + if( !strcmp(sectionName,"__la_symbol_ptr") || !strcmp(sectionName,"__la_sym_ptr2") || !strcmp(sectionName,"__la_sym_ptr3")) @@ -1483,7 +1494,7 @@ ocResolve_MachO(ObjectCode* oc) } else { - IF_DEBUG(linker, debugBelch("ocResolve_MachO: unknown section\n")); + IF_DEBUG(linker, debugBelch("ocResolve_MachO: unknown section %d/%d\n", i, oc->n_sections)); } } } @@ -1520,7 +1531,7 @@ ocResolve_MachO(ObjectCode* oc) for(int i = 0; i < oc->n_sections; i++) { - IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d\n", i)); + IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d/%d\n", i, oc->n_sections)); #if defined(aarch64_HOST_ARCH) if (!relocateSectionAarch64(oc, &oc->sections[i])) ===================================== rts/posix/GetTime.c ===================================== @@ -71,7 +71,6 @@ Time getCurrentThreadCPUTime(void) // support clock_getcpuclockid. Hence we prefer to use the Darwin-specific // path on Darwin, even if clock_gettime is available. #if defined(darwin_HOST_OS) - mach_port_t port = pthread_mach_thread_np(osThreadId()); thread_basic_info_data_t info = { 0 }; mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT; kern_return_t kern_err = thread_info(mach_thread_self(), THREAD_BASIC_INFO, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/831b66425aa3a24e769ace8d4649299ade021717 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/831b66425aa3a24e769ace8d4649299ade021717 You're receiving 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 23 03:16:22 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:16:22 -0400 Subject: [Git][ghc/ghc][master] Update commentary and slightly refactor GHC.Tc.Deriv.Infer Message-ID: <5ea108865f88c_616776d1c7466416d5@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 1 changed file: - compiler/GHC/Tc/Deriv/Infer.hs Changes: ===================================== compiler/GHC/Tc/Deriv/Infer.hs ===================================== @@ -803,28 +803,31 @@ simplifyDeriv pred tvs thetas ; solved_wanteds <- zonkWC solved_wanteds -- See [STEP DAC HOIST] - -- Split the resulting constraints into bad and good constraints, - -- building an @unsolved :: WantedConstraints@ representing all - -- the constraints we can't just shunt to the predicates. - -- See Note [Exotic derived instance contexts] + -- From the simplified constraints extract a subset 'good' that will + -- become the context 'min_theta' for the derived instance. ; let residual_simple = approximateWC True solved_wanteds - (bad, good) = partitionBagWith get_good residual_simple - - get_good :: Ct -> Either Ct PredType + good = mapMaybeBag get_good residual_simple + + -- Returns @Just p@ (where @p@ is the type of the Ct) if a Ct is + -- suitable to be inferred in the context of a derived instance. + -- Returns @Nothing@ if the Ct is too exotic. + -- See Note [Exotic derived instance contexts] for what + -- constitutes an exotic constraint. + get_good :: Ct -> Maybe PredType get_good ct | validDerivPred skol_set p , isWantedCt ct - = Right p + = Just p -- TODO: This is wrong -- NB re 'isWantedCt': residual_wanted may contain -- unsolved CtDerived and we stick them into the -- bad set so that reportUnsolved may decide what -- to do with them | otherwise - = Left ct + = Nothing where p = ctPred ct ; traceTc "simplifyDeriv outputs" $ - vcat [ ppr tvs_skols, ppr residual_simple, ppr good, ppr bad ] + vcat [ ppr tvs_skols, ppr residual_simple, ppr good ] -- Return the good unsolved constraints (unskolemizing on the way out.) ; let min_theta = mkMinimalBySCs id (bagToList good) @@ -838,6 +841,10 @@ simplifyDeriv pred tvs thetas -- The reverse substitution (sigh) -- See [STEP DAC RESIDUAL] + -- Ensure that min_theta is enough to solve /all/ the constraints in + -- solved_wanteds, by solving the implication constraint + -- + -- forall tvs. min_theta => solved_wanteds ; min_theta_vars <- mapM newEvVar min_theta ; (leftover_implic, _) <- buildImplicationFor tc_lvl skol_info tvs_skols View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c409961aea59d2fe2ae71036a1ae6d94c4ee05c8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c409961aea59d2fe2ae71036a1ae6d94c4ee05c8 You're receiving 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 23 03:17:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:17:01 -0400 Subject: [Git][ghc/ghc][master] Remove leftover comment in tcRnModule', redundant bind Message-ID: <5ea108ad7a695_616776d1c74664409b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 1 changed file: - compiler/GHC/Driver/Main.hs Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -519,36 +519,31 @@ tcRnModule' sum save_rn_syntax mod = do let allSafeOK = safeInferred dflags && tcSafeOK -- end of the safe haskell line, how to respond to user? - res <- if not (safeHaskellOn dflags) - || (safeInferOn dflags && not allSafeOK) - -- if safe Haskell off or safe infer failed, mark unsafe - then markUnsafeInfer tcg_res whyUnsafe - - -- module (could be) safe, throw warning if needed - else do - tcg_res' <- hscCheckSafeImports tcg_res - safe <- liftIO $ fst <$> readIORef (tcg_safeInfer tcg_res') - when safe $ do - case wopt Opt_WarnSafe dflags of - True - | safeHaskell dflags == Sf_Safe -> return () - | otherwise -> (logWarnings $ unitBag $ - makeIntoWarning (Reason Opt_WarnSafe) $ - mkPlainWarnMsg dflags (warnSafeOnLoc dflags) $ - errSafe tcg_res') - False | safeHaskell dflags == Sf_Trustworthy && - wopt Opt_WarnTrustworthySafe dflags -> - (logWarnings $ unitBag $ - makeIntoWarning (Reason Opt_WarnTrustworthySafe) $ - mkPlainWarnMsg dflags (trustworthyOnLoc dflags) $ - errTwthySafe tcg_res') - False -> return () - return tcg_res' - - -- apply plugins to the type checking result - - - return res + if not (safeHaskellOn dflags) + || (safeInferOn dflags && not allSafeOK) + -- if safe Haskell off or safe infer failed, mark unsafe + then markUnsafeInfer tcg_res whyUnsafe + + -- module (could be) safe, throw warning if needed + else do + tcg_res' <- hscCheckSafeImports tcg_res + safe <- liftIO $ fst <$> readIORef (tcg_safeInfer tcg_res') + when safe $ do + case wopt Opt_WarnSafe dflags of + True + | safeHaskell dflags == Sf_Safe -> return () + | otherwise -> (logWarnings $ unitBag $ + makeIntoWarning (Reason Opt_WarnSafe) $ + mkPlainWarnMsg dflags (warnSafeOnLoc dflags) $ + errSafe tcg_res') + False | safeHaskell dflags == Sf_Trustworthy && + wopt Opt_WarnTrustworthySafe dflags -> + (logWarnings $ unitBag $ + makeIntoWarning (Reason Opt_WarnTrustworthySafe) $ + mkPlainWarnMsg dflags (trustworthyOnLoc dflags) $ + errTwthySafe tcg_res') + False -> return () + return tcg_res' where pprMod t = ppr $ moduleName $ tcg_mod t errSafe t = quotes (pprMod t) <+> text "has been inferred as safe!" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/125aa2b8b8bb402d7819c3a35255b65c15b8bf9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/125aa2b8b8bb402d7819c3a35255b65c15b8bf9a You're receiving 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 23 03:17:45 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:17:45 -0400 Subject: [Git][ghc/ghc][master] RTS: workaround a Linux kernel bug in timerfd Message-ID: <5ea108d92d622_6167865d29c6648362@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - 1 changed file: - rts/posix/itimer/Pthread.c Changes: ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -122,10 +122,18 @@ static void *itimer_thread_func(void *_handle_tick) while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { - if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { - if (errno != EINTR) { - barf("Itimer: read(timerfd) failed: %s", strerror(errno)); - } + ssize_t r = read(timerfd, &nticks, sizeof(nticks)); + if ((r == 0) && (errno == 0)) { + /* r == 0 is expected only for non-blocking fd (in which case + * errno should be EAGAIN) but we use a blocking fd. + * + * Due to a kernel bug (cf https://lkml.org/lkml/2019/8/16/335) + * on some platforms we could see r == 0 and errno == 0. + */ + IF_DEBUG(scheduler, debugBelch("read(timerfd) returned 0 with errno=0. This is a known kernel bug. We just ignore it.")); + } + else if (r != sizeof(nticks) && errno != EINTR) { + barf("Itimer: read(timerfd) failed with %s and returned %zd", strerror(errno), r); } } else { if (rtsSleep(itimer_interval) != 0) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ea37b01b6ab16937f7b528b6bbae9fade9f1361 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ea37b01b6ab16937f7b528b6bbae9fade9f1361 You're receiving 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 23 03:49:09 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 22 Apr 2020 23:49:09 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 20 commits: stg-spec: Modify file paths according to new module hierarchy Message-ID: <5ea110359686c_616776d1c746651287@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - 4d9d03fe by Ryan Scott at 2020-04-22T23:49:01-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - becade49 by Ben Gamari at 2020-04-22T23:49:01-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 2fe7f17f by Ben Gamari at 2020-04-22T23:49:02-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match.hs-boot - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce47e6b489bf021c3093d8f90115ab04ba7694b5...2fe7f17f961c6d6696813e5fe2f96f3d9da98950 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce47e6b489bf021c3093d8f90115ab04ba7694b5...2fe7f17f961c6d6696813e5fe2f96f3d9da98950 You're receiving 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 23 11:33:02 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 23 Apr 2020 07:33:02 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 49 commits: Fix #18052 by using pprPrefixOcc in more places Message-ID: <5ea17ceec60d1_61673f81ba8fd52466845c1@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - 2daec0fb by Sebastian Graf at 2020-04-23T13:28:51+02:00 Nested CPR - - - - - 1e346217 by Sebastian Graf at 2020-04-23T13:28:53+02:00 Move tests from stranal to cpranal - - - - - a02325d6 by Sebastian Graf at 2020-04-23T13:28:53+02:00 Accept FacState - - - - - 75801295 by Sebastian Graf at 2020-04-23T13:29:45+02:00 Factor Cpr and Termination into a joint lattice As a result, we don't even have to export Termination from Cpr. Neat! Also I realised there is a simpler and more sound way to generate and unleash CPR signatures. - - - - - a906cf72 by Sebastian Graf at 2020-04-23T13:30:32+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - bc1e1781 by Sebastian Graf at 2020-04-23T13:30:33+02:00 stuff - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fdaaeee50f83688932aff91997b92d02408ae498...bc1e1781eca61d2502b708b9085a7c17dd54a2ed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fdaaeee50f83688932aff91997b92d02408ae498...bc1e1781eca61d2502b708b9085a7c17dd54a2ed You're receiving 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 23 13:26:08 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 23 Apr 2020 09:26:08 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Debug output Message-ID: <5ea197707ca2_6167865d29c66972eb@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: fad4dd62 by Sebastian Graf at 2020-04-23T15:26:03+02:00 Debug output - - - - - 1 changed file: - compiler/GHC/Core/Opt/CprAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -138,7 +138,7 @@ cprAnal, cprAnal' -> CoreExpr -- ^ expression to be denoted by a 'CprType' -> (CprType, CoreExpr) -- ^ the updated expression and its 'CprType' -cprAnal env args e = pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ +cprAnal env args e = -- pprTraceWith "cprAnal" (\res -> ppr (fst (res)) $$ ppr e) $ cprAnal' env args e cprAnal' _ _ (Lit lit) = (whnfTermCprType, Lit lit) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fad4dd628baff152151a6d3af318fd25eda24303 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fad4dd628baff152151a6d3af318fd25eda24303 You're receiving 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 23 13:57:56 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 23 Apr 2020 09:57:56 -0400 Subject: [Git][ghc/ghc][wip/T18043] rts: Flush eventlog buffers from flushEventLog Message-ID: <5ea19ee419a7b_6167865d29c669982@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18043 at Glasgow Haskell Compiler / GHC Commits: b643e4f9 by Ben Gamari at 2020-04-23T09:57:42-04:00 rts: Flush eventlog buffers from flushEventLog As noted in #18043, flushTrace failed flush anything beyond the writer. This means that a significant amount of data sitting in capability-local event buffers may never get flushed, despite the users' pleads for us to flush. Fix this by making flushEventLog flush all of the event buffers before flushing the writer. Fixes #18043. - - - - - 10 changed files: - includes/RtsAPI.h - includes/rts/EventLogWriter.h - libraries/base/Debug/Trace.hs - rts/Capability.c - rts/Capability.h - rts/Schedule.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/RtsAPI.h ===================================== @@ -17,7 +17,6 @@ extern "C" { #include "HsFFI.h" #include "rts/Time.h" -#include "rts/EventLogWriter.h" /* * Running the scheduler @@ -47,6 +46,9 @@ typedef struct CapabilityPublic_ { StgRegTable r; } CapabilityPublic; +/* N.B. this needs the Capability declaration above. */ +#include "rts/EventLogWriter.h" + /* ---------------------------------------------------------------------------- RTS configuration settings, for passing to hs_init_ghc() ------------------------------------------------------------------------- */ ===================================== includes/rts/EventLogWriter.h ===================================== @@ -64,3 +64,8 @@ bool startEventLogging(const EventLogWriter *writer); * Stop event logging and destroy the current EventLogWriter. */ void endEventLogging(void); + +/* + * Flush the eventlog. cap can be NULL if one is not held. + */ +void flushEventLog(Capability **cap); ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -37,6 +37,7 @@ module Debug.Trace ( -- $eventlog_tracing traceEvent, traceEventIO, + flushEventLog, -- * Execution phase markers -- $markers @@ -319,3 +320,11 @@ traceMarkerIO :: String -> IO () traceMarkerIO msg = GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) + +-- | Immediately flush the event log, if enabled. +-- +-- @since 4.15.0.0 +flushEventLog :: IO () +flushEventLog = c_flushEventLog nullPtr + +foreign import ccall "flushEventLog" c_flushEventLog :: Ptr () -> IO () ===================================== rts/Capability.c ===================================== @@ -23,6 +23,7 @@ #include "Schedule.h" #include "Sparks.h" #include "Trace.h" +#include "eventlog/EventLog.h" // for flushLocalEventsBuf #include "sm/GC.h" // for gcWorkerThread() #include "STM.h" #include "RtsUtils.h" @@ -885,6 +886,10 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed) debugTrace(DEBUG_nonmoving_gc, "Flushing update remembered set blocks..."); break; + case SYNC_FLUSH_EVENT_LOG: + flushLocalEventsBuf(cap); + break; + default: break; } ===================================== rts/Capability.h ===================================== @@ -263,7 +263,8 @@ typedef enum { SYNC_OTHER, SYNC_GC_SEQ, SYNC_GC_PAR, - SYNC_FLUSH_UPD_REM_SET + SYNC_FLUSH_UPD_REM_SET, + SYNC_FLUSH_EVENT_LOG } SyncType; // ===================================== rts/Schedule.c ===================================== @@ -2035,7 +2035,7 @@ forkProcess(HsStablePtr *entry stopTimer(); // See #4074 #if defined(TRACING) - flushEventLog(); // so that child won't inherit dirty file buffers + flushAllCapsEventsBufs(); // so that child won't inherit dirty file buffers #endif pid = fork(); ===================================== rts/Trace.c ===================================== @@ -117,10 +117,10 @@ void resetTracing (void) restartEventLogging(); } -void flushTrace (void) +void flushTrace () { if (eventlog_enabled) { - flushEventLog(); + flushEventLog(NULL); } } ===================================== rts/Trace.h ===================================== @@ -319,7 +319,6 @@ void traceConcSweepEnd(void); void traceConcUpdRemSetFlush(Capability *cap); void traceNonmovingHeapCensus(uint32_t log_blk_size, const struct NonmovingAllocCensus *census); - void flushTrace(void); #else /* !TRACING */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -16,6 +16,7 @@ #include "RtsUtils.h" #include "Stats.h" #include "EventLog.h" +#include "Schedule.h" #include #include @@ -271,7 +272,7 @@ stopEventLogWriter(void) } void -flushEventLog(void) +flushEventLogWriter(void) { if (event_log_writer != NULL && event_log_writer->flushEventLog != NULL) { @@ -1565,6 +1566,40 @@ void postEventType(EventsBuf *eb, EventType *et) postInt32(eb, EVENT_ET_END); } +void flushLocalEventsBuf(Capability *cap) +{ + EventsBuf *eb = &capEventBuf[cap->no]; + printAndClearEventBuf(eb); +} + +// Flush all capabilities' event buffers when we already hold all capabilities. +// Used during forkProcess. +void flushAllCapsEventsBufs() +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + + for (int i=0; i < n_capabilities; i++) { + flushLocalEventsBuf(capabilities[i]); + } + flushEventLogWriter(); +} + +void flushEventLog(Capability **cap USED_IF_THREADS) +{ + ACQUIRE_LOCK(&eventBufMutex); + printAndClearEventBuf(&eventBuf); + RELEASE_LOCK(&eventBufMutex); + +#if defined(THREADED_RTS) + Task *task = getTask(); + stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); + releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); +#endif + flushEventLogWriter(); +} + #else enum EventLogStatus eventLogStatus(void) @@ -1578,4 +1613,6 @@ bool startEventLogging(const EventLogWriter *writer STG_UNUSED) { void endEventLogging(void) {} +void flushEventLog(Capability **cap STG_UNUSED) {} + #endif /* TRACING */ ===================================== rts/eventlog/EventLog.h ===================================== @@ -28,8 +28,11 @@ void initEventLogging(void); void restartEventLogging(void); void freeEventLogging(void); void abortEventLogging(void); // #4512 - after fork child needs to abort -void flushEventLog(void); // event log inherited from parent +void flushEventLogWriter(void); // event log inherited from parent void moreCapEventBufs (uint32_t from, uint32_t to); +void flushLocalEventsBuf(Capability *cap); +void flushAllCapsEventsBufs(void); +void flushAllEventsBufs(Capability *cap); /* * Post a scheduler event to the capability's event buffer (an event @@ -175,6 +178,9 @@ void postNonmovingHeapCensus(int log_blk_size, #else /* !TRACING */ +INLINE_HEADER void flushLocalEventsBuf(Capability *cap STG_UNUSED) +{ /* nothing */ } + INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, EventTypeNum tag STG_UNUSED, StgThreadID id STG_UNUSED, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b643e4f9dd7b6a4731816598fb9457b1bef8914d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b643e4f9dd7b6a4731816598fb9457b1bef8914d You're receiving 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 23 14:11:18 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Thu, 23 Apr 2020 10:11:18 -0400 Subject: [Git][ghc/ghc][wip/lexical-negation] 28 commits: Derive Ord instance for Extension Message-ID: <5ea1a206e4d2e_61673f81cc6e89e867045b5@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/lexical-negation at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - 1010cc5f by Vladislav Zavialov at 2020-04-23T17:11:00+03:00 Implement -XLexicalNegation (GHC Proposal #229) This patch introduces a new extension, -XLexicalNegation, which detects whether the minus sign stands for negation or subtraction using the whitespace-based rules described in GHC Proposal #229. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/035b5d1ff464bd8c4bdaab30855d1bc1f2f1f748...1010cc5f62774d4137b171ba2e9de811c47c5729 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/035b5d1ff464bd8c4bdaab30855d1bc1f2f1f748...1010cc5f62774d4137b171ba2e9de811c47c5729 You're receiving 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 23 14:23:19 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Thu, 23 Apr 2020 10:23:19 -0400 Subject: [Git][ghc/ghc][wip/semigroup-sdoc] 18 commits: stg-spec: Modify file paths according to new module hierarchy Message-ID: <5ea1a4d7e4f3f_61673f81afeb5fbc6705171@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/semigroup-sdoc at Glasgow Haskell Compiler / GHC Commits: ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - e21f3023 by Vladislav Zavialov at 2020-04-23T17:21:28+03:00 Use Semigroup's (<>) for Doc/SDoc Before this patch, Outputable.hs defined its own (<>) which caused conflicts with (Data.Semigroup.<>) and thus led to inconvenience. However, replacing it is not trivial due to a different fixity: http://www.haskell.org/pipermail/libraries/2011-November/017066.html Nevertheless, it is possible to update the pretty-printing code to work with (<>) of a different fixitiy, and that's what this patch implements. Now Doc and SDoc are instances of Semigroup. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Plugins.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Expr.hs-boot - compiler/GHC/HsToCore/GuardedRHSs.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match.hs-boot - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Recomp.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/0fa283769d3427b946dbe7567d24735388897ee1...e21f3023b095d9bbd000330b56aaaa2977134335 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0fa283769d3427b946dbe7567d24735388897ee1...e21f3023b095d9bbd000330b56aaaa2977134335 You're receiving 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 23 14:44:06 2020 From: gitlab at gitlab.haskell.org (Josh Meredith) Date: Thu, 23 Apr 2020 10:44:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/coreField Message-ID: <5ea1a9b6a223c_6167e5c4f146711924@gitlab.haskell.org.mail> Josh Meredith pushed new branch wip/coreField at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/coreField You're receiving 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 23 15:39:36 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 23 Apr 2020 11:39:36 -0400 Subject: [Git][ghc/ghc][master] Create di_scoped_tvs for associated data family instances properly Message-ID: <5ea1b6b811e2_61673f81e7063210672143e@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 3 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/deriving/should_compile/T18055.hs - testsuite/tests/deriving/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -77,6 +77,7 @@ import BooleanFormula ( isUnsatisfied, pprBooleanFormulaNice ) import qualified GHC.LanguageExtensions as LangExt import Control.Monad +import Data.Tuple import Maybes import Data.List( mapAccumL ) @@ -460,7 +461,7 @@ tcLocalInstDecl (L loc (TyFamInstD { tfid_inst = decl })) ; return ([], [fam_inst], []) } tcLocalInstDecl (L loc (DataFamInstD { dfid_inst = decl })) - = do { (fam_inst, m_deriv_info) <- tcDataFamInstDecl NotAssociated (L loc decl) + = do { (fam_inst, m_deriv_info) <- tcDataFamInstDecl NotAssociated emptyVarEnv (L loc decl) ; return ([], [fam_inst], maybeToList m_deriv_info) } tcLocalInstDecl (L loc (ClsInstD { cid_inst = decl })) @@ -483,6 +484,9 @@ tcClsInstDecl (L loc (ClsInstDecl { cid_poly_ty = hs_ty, cid_binds = binds ; (subst, skol_tvs) <- tcInstSkolTyVars tyvars ; let tv_skol_prs = [ (tyVarName tv, skol_tv) | (tv, skol_tv) <- tyvars `zip` skol_tvs ] + -- Map from the skolemized Names to the original Names. + -- See Note [Associated data family instances and di_scoped_tvs]. + tv_skol_env = mkVarEnv $ map swap tv_skol_prs n_inferred = countWhile ((== Inferred) . binderArgFlag) $ fst $ splitForAllVarBndrs dfun_ty visible_skol_tvs = drop n_inferred skol_tvs @@ -497,7 +501,7 @@ tcClsInstDecl (L loc (ClsInstDecl { cid_poly_ty = hs_ty, cid_binds = binds mb_info = InClsInst { ai_class = clas , ai_tyvars = visible_skol_tvs , ai_inst_env = mini_env } - ; df_stuff <- mapAndRecoverM (tcDataFamInstDecl mb_info) adts + ; df_stuff <- mapAndRecoverM (tcDataFamInstDecl mb_info tv_skol_env) adts ; tf_insts1 <- mapAndRecoverM (tcTyFamInstDecl mb_info) ats -- Check for missing associated types and build them @@ -634,10 +638,16 @@ For some reason data family instances are a lot more complicated than type family instances -} -tcDataFamInstDecl :: AssocInstInfo - -> LDataFamInstDecl GhcRn -> TcM (FamInst, Maybe DerivInfo) +tcDataFamInstDecl :: + AssocInstInfo + -> TyVarEnv Name -- If this is an associated data family instance, maps the + -- parent class's skolemized type variables to their + -- original Names. If this is a non-associated instance, + -- this will be empty. + -- See Note [Associated data family instances and di_scoped_tvs]. + -> LDataFamInstDecl GhcRn -> TcM (FamInst, Maybe DerivInfo) -- "newtype instance" and "data instance" -tcDataFamInstDecl mb_clsinfo +tcDataFamInstDecl mb_clsinfo tv_skol_env (L loc decl@(DataFamInstDecl { dfid_eqn = HsIB { hsib_ext = imp_vars , hsib_body = FamEqn { feqn_bndrs = mb_bndrs @@ -749,11 +759,12 @@ tcDataFamInstDecl mb_clsinfo ; checkValidCoAxBranch fam_tc ax_branch ; checkValidTyCon rep_tc - ; let m_deriv_info = case derivs of + ; let scoped_tvs = map mk_deriv_info_scoped_tv_pr (tyConTyVars rep_tc) + m_deriv_info = case derivs of L _ [] -> Nothing L _ preds -> Just $ DerivInfo { di_rep_tc = rep_tc - , di_scoped_tvs = mkTyVarNamePairs (tyConTyVars rep_tc) + , di_scoped_tvs = scoped_tvs , di_clauses = preds , di_ctxt = tcMkDataFamInstCtxt decl } @@ -784,6 +795,45 @@ tcDataFamInstDecl mb_clsinfo = go pats (Bndr tv tcb_vis : etad_tvs) go pats etad_tvs = (reverse (map fstOf3 pats), etad_tvs) + -- Create a Name-TyVar mapping to bring into scope when typechecking any + -- deriving clauses this data family instance may have. + -- See Note [Associated data family instances and di_scoped_tvs]. + mk_deriv_info_scoped_tv_pr :: TyVar -> (Name, TyVar) + mk_deriv_info_scoped_tv_pr tv = + let n = lookupWithDefaultVarEnv tv_skol_env (tyVarName tv) tv + in (n, tv) + +{- +Note [Associated data family instances and di_scoped_tvs] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Some care is required to implement `deriving` correctly for associated data +family instances. Consider this example from #18055: + + class C a where + data D a + + class X a b + + instance C (Maybe a) where + data D (Maybe a) deriving (X a) + +When typechecking the `X a` in `deriving (X a)`, we must ensure that the `a` +from the instance header is brought into scope. This is the role of +di_scoped_tvs, which maps from the original, renamed `a` to the skolemized, +typechecked `a`. When typechecking the `deriving` clause, this mapping will be +consulted when looking up the `a` in `X a`. + +A naïve attempt at creating the di_scoped_tvs is to simply reuse the +tyConTyVars of the representation TyCon for `data D (Maybe a)`. This is only +half correct, however. We do want the typechecked `a`'s Name in the /range/ +of the mapping, but we do not want it in the /domain/ of the mapping. +To ensure that the original `a`'s Name ends up in the domain, we consult a +TyVarEnv (passed as an argument to tcDataFamInstDecl) that maps from the +typechecked `a`'s Name to the original `a`'s Name. In the even that +tcDataFamInstDecl is processing a non-associated data family instance, this +TyVarEnv will simply be empty, and there is nothing to worry about. +-} + ----------------------- tcDataFamInstHeader :: AssocInstInfo -> TyCon -> [Name] -> Maybe [LHsTyVarBndr GhcRn] ===================================== testsuite/tests/deriving/should_compile/T18055.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies #-} +module Bug where + +import Data.Kind + +----- + +data Block m = Block + +class NoThunks m where + +newtype AllowThunk a = AllowThunk a + +class GetHeader blk where + data family Header blk :: Type + +instance GetHeader (Block m) where + newtype Header (Block m) = BlockHeader { main :: Header m } + deriving NoThunks via AllowThunk (Header (Block m)) + +----- + +class C a where + data D a + +class X a b + +instance C (Maybe a) where + data D (Maybe a) deriving (X a) + +instance C [a] where + newtype D [a] = MkDList Bool + +newtype MyList a = MkMyList [a] + +instance C (MyList a) where + newtype D (MyList a) = MkDMyList Bool + deriving (X a) via D [a] ===================================== testsuite/tests/deriving/should_compile/all.T ===================================== @@ -123,3 +123,4 @@ test('T17324', normal, compile, ['']) test('T17339', normal, compile, ['-ddump-simpl -dsuppress-idinfo -dno-typeable-binds']) test('T17880', normal, compile, ['']) +test('T18055', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd8409c26d4370bf2cdcd76801974e99a9adf7b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd8409c26d4370bf2cdcd76801974e99a9adf7b0 You're receiving 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 23 15:40:12 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 23 Apr 2020 11:40:12 -0400 Subject: [Git][ghc/ghc][master] hadrian/ghci: Allow arguments to be passed to GHCi Message-ID: <5ea1b6dc7ff53_6167e5b4fc4672502b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 3 changed files: - hadrian/ghci - hadrian/ghci-cabal - hadrian/ghci-stack Changes: ===================================== hadrian/ghci ===================================== @@ -1,4 +1,4 @@ #!/usr/bin/env bash # By default on Linux/MacOS we build Hadrian using Cabal -(. "hadrian/ghci-cabal" "$@") +(. "hadrian/ghci-cabal" $@) ===================================== hadrian/ghci-cabal ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" -ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" +ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m ===================================== hadrian/ghci-stack ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci "$@" | tr '\n\r' ' ')" +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/339e8ece1c844af5c9165efbc3a928890c2f75c7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/339e8ece1c844af5c9165efbc3a928890c2f75c7 You're receiving 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 23 15:40:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 23 Apr 2020 11:40:48 -0400 Subject: [Git][ghc/ghc][master] testsuite: Don't attempt to read .std{err, out} files if they don't exist Message-ID: <5ea1b70099884_6167865d29c6727676@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - 1 changed file: - testsuite/driver/testlib.py Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -1787,7 +1787,11 @@ def stdout_ok(name: TestName, way: WayName) -> bool: expected_stdout_file, actual_stdout_file) def read_stdout( name: TestName ) -> str: - return in_testdir(name, 'run.stdout').read_text(encoding='UTF-8') + path = in_testdir(name, 'run.stdout') + if path.exists(): + return path.read_text(encoding='UTF-8') + else: + return '' def dump_stdout( name: TestName ) -> None: s = read_stdout(name).strip() @@ -1805,7 +1809,11 @@ def stderr_ok(name: TestName, way: WayName) -> bool: whitespace_normaliser=normalise_whitespace) def read_stderr( name: TestName ) -> str: - return in_testdir(name, 'run.stderr').read_text(encoding='UTF-8') + path = in_testdir(name, 'run.stderr') + if path.exists(): + return path.read_text(encoding='UTF-8') + else: + return '' def dump_stderr( name: TestName ) -> None: s = read_stderr(name).strip() View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5946c85abcf66555cdbcd3eed02cb8f512b6110c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5946c85abcf66555cdbcd3eed02cb8f512b6110c You're receiving 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 23 16:12:39 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 23 Apr 2020 12:12:39 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Create di_scoped_tvs for associated data family instances properly Message-ID: <5ea1be77c9ac6_6167e5c4f146731881@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - 6034b7c9 by John Ericson at 2020-04-23T12:12:22-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - c5b9828c by mniip at 2020-04-23T12:12:31-04:00 Add :doc to GHC.Prim - - - - - 1ed4d527 by mniip at 2020-04-23T12:12:31-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 4c6190d2 by mniip at 2020-04-23T12:12:31-04:00 GHC.Prim docs: note and test - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2fe7f17f961c6d6696813e5fe2f96f3d9da98950...4c6190d248f0dbe4af1b307c13cb47978495d9f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2fe7f17f961c6d6696813e5fe2f96f3d9da98950...4c6190d248f0dbe4af1b307c13cb47978495d9f0 You're receiving 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 23 16:42:11 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 23 Apr 2020 12:42:11 -0400 Subject: [Git][ghc/ghc][wip/T17775] 43 commits: GHC.Core.Opt renaming Message-ID: <5ea1c56326e05_6167e5b4fc46745627@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - 330b985d by Simon Peyton Jones at 2020-04-23T11:55:11+01:00 Simplify subsumption This patch implements GHC Proposal 287: Simplify subsumption and ticket #17775. The highlights are: * No deeplyInstantiate or deeplySkolemise * No tcSubTypeDS Everything else is a knock-on effect. I did a bit of renaming to make things consistent * tcPolyExpr becomes tcCheckPolyExpr ditto tcPolyExprNC * Add new function tcCheckMonoExpr e ty = tcMon0Expr expr (mkCheckExpType ty) and use it This all comopiles, but needs some eta-expansion in haskeline, and doubtless other packages. - - - - - c81a5b2a by Simon Peyton Jones at 2020-04-23T11:58:54+01:00 Further refactoring and simplification Reviewed the main changes with Richard I had to do eta-expansion in a number of tests: T10283 T10390 T14488 T1634 T4284 T9569a T9834 tc145 tc160 tc208 tc210 twins - - - - - 4f21c6ad by Ben Gamari at 2020-04-23T11:58:54+01:00 Bump haskeline submodule - - - - - 5d04b0ff by Simon Peyton Jones at 2020-04-23T11:58:54+01:00 Delete commented-out code - - - - - 7beff0d2 by Simon Peyton Jones at 2020-04-23T11:58:54+01:00 Fix (breaking) typo - - - - - 4ce60c8b by Simon Peyton Jones at 2020-04-23T11:58:55+01:00 Improve decomposition for FunTys This just improves error messages, avoiding Couldn't match type ‘Char’ with ‘Show a -> Char’ - - - - - 7dd9f2ab by Ryan Scott at 2020-04-23T11:58:55+01:00 Bump Cabal submodule As well as some miscellaneous fixes needed to make GHC itself compile under simplified subsumption. - - - - - 2d907b65 by Simon Peyton Jones at 2020-04-23T11:59:54+01:00 Wibbles * Get expected/actual the right way round * Relevant-bindings fixes - - - - - 2ed80bac by Simon Peyton Jones at 2020-04-23T12:07:17+01:00 A lot more wibbles * Made String wired-in, so that "foo" :: String rather than "foo" :: [Char] * isTauTy: account for => * Bring dicts into scope when desugaring HsWrappers: addTyCsDs and hsWrapDictBinders * Improve reporting for occurs checks where skolems are involved e.g. 10715b, mc19, tcfail193, T13674, T4272, T3169, T7758, 7148 Payload is in the first case of mkTyVarEqErr * solveLocalEqualitesX: fail faster. we want to fail fast in T11142 Another example: T15629 And keep all equalities in dropMisleading. This gives better reporting in T12593 for example. * Move checkDataKindSig after the solveEqualities and zonk, obviously! * Move ic_telescope into ForAllSkol; a nice win. * Pretty-printing AbsBinds We are now very close to green - - - - - 1c7d72bf by Simon Peyton Jones at 2020-04-23T12:08:22+01:00 More wibbles - - - - - dcb92d28 by Simon Peyton Jones at 2020-04-23T12:08:24+01:00 Wibbles - - - - - 3e4b833d by Simon Peyton Jones at 2020-04-23T12:08:56+01:00 Lots more wibbles Mainly re-engineering GHC.Tc.Errors - - - - - 403733ac by Simon Peyton Jones at 2020-04-23T17:40:55+01:00 Lots of fixing ...esp on Tc.Errors and error messages - - - - - 30 changed files: - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Lexer.x - compiler/GHC/Cmm/Monad.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6438742bb8c3f6ebbf2bb9e9a8a0a7bd076fe9a...403733acdce53c406dae2836a085372374635cc9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6438742bb8c3f6ebbf2bb9e9a8a0a7bd076fe9a...403733acdce53c406dae2836a085372374635cc9 You're receiving 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 23 19:07:59 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 23 Apr 2020 15:07:59 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] A slew of testsuite changes Message-ID: <5ea1e78f32355_61673f81ee93dc1c67704e0@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: d62719d9 by Sebastian Graf at 2020-04-23T21:04:29+02:00 A slew of testsuite changes - - - - - 30 changed files: - testsuite/tests/cpranal/sigs/CaseBinderCPR.stderr - testsuite/tests/cpranal/sigs/FacState.stderr - testsuite/tests/cpranal/sigs/T10694.stderr - + testsuite/tests/cpranal/sigs/T1600.hs - + testsuite/tests/cpranal/sigs/T1600.stderr - testsuite/tests/cpranal/sigs/T5075.stderr - testsuite/tests/cpranal/sigs/all.T - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4201.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr - testsuite/tests/simplCore/should_compile/par01.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/HyperStrUse.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/StrAnalExample.stderr - testsuite/tests/stranal/sigs/T12370.stderr - testsuite/tests/stranal/sigs/T17932.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d62719d99a8631114021da8727cab89721ab77e6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d62719d99a8631114021da8727cab89721ab77e6 You're receiving 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 23 19:10:57 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 23 Apr 2020 15:10:57 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Fix T1600 Message-ID: <5ea1e84155da7_61673f81cc6e89e86771289@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: fec46cbb by Sebastian Graf at 2020-04-23T21:10:51+02:00 Fix T1600 - - - - - 2 changed files: - testsuite/tests/cpranal/sigs/T1600.hs - testsuite/tests/cpranal/sigs/T1600.stderr Changes: ===================================== testsuite/tests/cpranal/sigs/T1600.hs ===================================== @@ -1,20 +1,23 @@ -module T1600 where +module Lib where -- pretty strict -fac :: Int -> a -> (a, Int) -fac n s | n < 2 = (s,1) - | otherwise = case fac (n-1) s of (s',n') -> let n'' = n*n' in n'' `seq` (s',n'') +fac1 :: Int -> a -> (a, Int) +fac1 n s | n < 2 = (s,1) + | otherwise = case fac1 (n-1) s of (s',n') -> let n'' = n*n' in n'' `seq` (s',n'') -- lazier, but Int still has CPR fac2 :: Int -> a -> (a, Int) fac2 n s | n < 2 = (s,1) - | otherwise = case fac (n-1) s of (s',n') -> (s',n'*n') + | otherwise = case fac2 (n-1) s of (s',n') -> (s',n'*n') --- even lazier, no CPR on Int +-- even lazier, but evaluation of the Int doesn't terminate rapidly! +-- Thus, we may not WW for the nested Int. +-- Otherwise @fac3 99999 () `seq` ()@ (which should terminate rapidly) +-- evaluates more than necessary. fac3 :: Int -> a -> (a, Int) fac3 n s | n < 2 = (s,1) - | otherwise = let (s',n') = fac (n-1) s in (s',n'*n') + | otherwise = let (s',n') = fac3 (n-1) s in (s',n'*n') facIO :: Int -> IO Int facIO n | n < 2 = return 1 ===================================== testsuite/tests/cpranal/sigs/T1600.stderr ===================================== @@ -1,7 +1,9 @@ ==================== Cpr signatures ==================== -FacState.$trModule: #1(#, #) 1(1(-), 1(-)) -FacState.fac: *1(*, #) 1(-, 1(-)) -FacState.facIO: *1(*, #) 1(-, 1(-)) +Lib.$trModule: #c1(#c1(#), #c1(#)) +Lib.fac1: *c1(*, #c1(#)) +Lib.fac2: *c1(*, #c1(#)) +Lib.fac3: *c1(*, *c1(#)) +Lib.facIO: *c1(*, #c1(#)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fec46cbba409e405f49d1aade0ad5f639a1632e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fec46cbba409e405f49d1aade0ad5f639a1632e4 You're receiving 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 23 22:33:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 23 Apr 2020 18:33:01 -0400 Subject: [Git][ghc/ghc][master] Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5ea2179dd8693_61673f81ee93dc1c6802089@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 29 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs - testsuite/tests/ghc-api/T6145.hs - utils/haddock Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -358,6 +358,9 @@ deriving instance Data (Pat GhcPs) deriving instance Data (Pat GhcRn) deriving instance Data (Pat GhcTc) +deriving instance Data CoPat +deriving instance Data ConPatTc + deriving instance Data ListPatTc -- deriving instance (DataIdLR p p, Data body) => Data (HsRecFields p body) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -10,6 +10,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] @@ -23,8 +24,11 @@ {-# LANGUAGE LambdaCase #-} module GHC.Hs.Pat ( - Pat(..), InPat, OutPat, LPat, + Pat(..), LPat, + ConPatTc (..), + CoPat (..), ListPatTc(..), + ConLikeP, HsConPatDetails, hsConPatArgs, HsRecFields(..), HsRecField'(..), LHsRecField', @@ -59,7 +63,6 @@ import GHC.Tc.Types.Evidence import GHC.Types.Basic -- others: import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} ) -import GHC.Driver.Session ( gopt, GeneralFlag(Opt_PrintTypecheckerElaboration) ) import GHC.Builtin.Types import GHC.Types.Var import GHC.Types.Name.Reader ( RdrName ) @@ -71,12 +74,10 @@ import GHC.Core.Type import GHC.Types.SrcLoc import Bag -- collect ev vars from pats import Maybes +import GHC.Types.Name (Name) -- libraries: import Data.Data hiding (TyCon,Fixity) -type InPat p = LPat p -- No 'Out' constructors -type OutPat p = LPat p -- No 'In' constructors - type LPat p = XRec p Pat -- | Pattern @@ -173,30 +174,12 @@ data Pat p -- For details on above see note [Api annotations] in GHC.Parser.Annotation ------------ Constructor patterns --------------- - | ConPatIn (Located (IdP p)) - (HsConPatDetails p) - -- ^ Constructor Pattern In - - | ConPatOut { - pat_con :: Located ConLike, - pat_arg_tys :: [Type], -- The universal arg types, 1-1 with the universal - -- tyvars of the constructor/pattern synonym - -- Use (conLikeResTy pat_con pat_arg_tys) to get - -- the type of the pattern - - pat_tvs :: [TyVar], -- Existentially bound type variables - -- in correctly-scoped order e.g. [k:*, x:k] - pat_dicts :: [EvVar], -- Ditto *coercion variables* and *dictionaries* - -- One reason for putting coercion variable here, I think, - -- is to ensure their kinds are zonked - - pat_binds :: TcEvBinds, -- Bindings involving those dictionaries - pat_args :: HsConPatDetails p, - pat_wrap :: HsWrapper -- Extra wrapper to pass to the matcher - -- Only relevant for pattern-synonyms; - -- ignored for data cons + | ConPat { + pat_con_ext :: XConPat p, + pat_con :: Located (ConLikeP p), + pat_args :: HsConPatDetails p } - -- ^ Constructor Pattern Out + -- ^ Constructor Pattern ------------ View patterns --------------- -- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnRarrow' @@ -262,17 +245,6 @@ data Pat p -- ^ Pattern with a type signature - ------------ Pattern coercions (translation only) --------------- - | CoPat (XCoPat p) - HsWrapper -- Coercion Pattern - -- If co :: t1 ~ t2, p :: t2, - -- then (CoPat co p) :: t1 - (Pat p) -- Why not LPat? Ans: existing locn will do - Type -- Type of whole pattern, t1 - -- During desugaring a (CoPat co pat) turns into a cast with 'co' on - -- the scrutinee, followed by a match on 'pat' - -- ^ Coercion Pattern - -- | Trees that Grow extension point for new constructors | XPat !(XXPat p) @@ -306,6 +278,10 @@ type instance XTuplePat GhcPs = NoExtField type instance XTuplePat GhcRn = NoExtField type instance XTuplePat GhcTc = [Type] +type instance XConPat GhcPs = NoExtField +type instance XConPat GhcRn = NoExtField +type instance XConPat GhcTc = ConPatTc + type instance XSumPat GhcPs = NoExtField type instance XSumPat GhcRn = NoExtField type instance XSumPat GhcTc = [Type] @@ -329,9 +305,16 @@ type instance XSigPat GhcPs = NoExtField type instance XSigPat GhcRn = NoExtField type instance XSigPat GhcTc = Type -type instance XCoPat (GhcPass _) = NoExtField +type instance XXPat GhcPs = NoExtCon +type instance XXPat GhcRn = NoExtCon +type instance XXPat GhcTc = CoPat + -- After typechecking, we add one extra constructor: CoPat -type instance XXPat (GhcPass _) = NoExtCon +type family ConLikeP x + +type instance ConLikeP GhcPs = RdrName -- IdP GhcPs +type instance ConLikeP GhcRn = Name -- IdP GhcRn +type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- @@ -344,6 +327,52 @@ hsConPatArgs (PrefixCon ps) = ps hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs) hsConPatArgs (InfixCon p1 p2) = [p1,p2] +-- | This is the extension field for ConPat, added after typechecking +-- It adds quite a few extra fields, to support elaboration of pattern matching. +data ConPatTc + = ConPatTc + { -- | The universal arg types 1-1 with the universal + -- tyvars of the constructor/pattern synonym + -- Use (conLikeResTy pat_con cpt_arg_tys) to get + -- the type of the pattern + cpt_arg_tys :: [Type] + + , -- | Existentially bound type variables + -- in correctly-scoped order e.g. [k:* x:k] + cpt_tvs :: [TyVar] + + , -- | Ditto *coercion variables* and *dictionaries* + -- One reason for putting coercion variable here I think + -- is to ensure their kinds are zonked + cpt_dicts :: [EvVar] + + , -- | Bindings involving those dictionaries + cpt_binds :: TcEvBinds + + , -- ^ Extra wrapper to pass to the matcher + -- Only relevant for pattern-synonyms; + -- ignored for data cons + cpt_wrap :: HsWrapper + } + +-- | Coercion Pattern (translation only) +-- +-- During desugaring a (CoPat co pat) turns into a cast with 'co' on the +-- scrutinee, followed by a match on 'pat'. +data CoPat + = CoPat + { -- | Coercion Pattern + -- If co :: t1 ~ t2, p :: t2, + -- then (CoPat co p) :: t1 + co_cpt_wrap :: HsWrapper + + , -- | Why not LPat? Ans: existing locn will do + co_pat_inner :: Pat GhcTc + + , -- | Type of whole pattern, t1 + co_pat_ty :: Type + } + -- | Haskell Record Fields -- -- HsRecFields is used only for patterns and expressions (not data type @@ -498,16 +527,23 @@ pprParendLPat :: (OutputableBndrId p) => PprPrec -> LPat (GhcPass p) -> SDoc pprParendLPat p = pprParendPat p . unLoc -pprParendPat :: (OutputableBndrId p) - => PprPrec -> Pat (GhcPass p) -> SDoc -pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \print_tc_elab -> - if need_parens print_tc_elab pat - then parens (pprPat pat) - else pprPat pat +pprParendPat :: forall p. OutputableBndrId p + => PprPrec + -> Pat (GhcPass p) + -> SDoc +pprParendPat p pat = sdocOption sdocPrintTypecheckerElaboration $ \ print_tc_elab -> + if need_parens print_tc_elab pat + then parens (pprPat pat) + else pprPat pat where need_parens print_tc_elab pat - | CoPat {} <- pat = print_tc_elab - | otherwise = patNeedsParens p pat + | GhcTc <- ghcPass @p + , XPat ext <- pat + , CoPat {} <- ext + = print_tc_elab + + | otherwise + = patNeedsParens p pat -- For a CoPat we need parens if we are going to show it, which -- we do if -fprint-typechecker-elaboration is on (c.f. pprHsWrapper) -- But otherwise the CoPat is discarded, so it @@ -527,12 +563,6 @@ pprPat (NPat _ l Nothing _) = ppr l pprPat (NPat _ l (Just _) _) = char '-' <> ppr l pprPat (NPlusKPat _ n k _ _ _) = hcat [ppr n, char '+', ppr k] pprPat (SplicePat _ splice) = pprSplice splice -pprPat (CoPat _ co pat _) = pprIfTc @p $ - sdocWithDynFlags $ \ dflags -> - if gopt Opt_PrintTypecheckerElaboration dflags - then hang (text "CoPat" <+> parens (ppr co)) - 2 (pprParendPat appPrec pat) - else pprPat pat pprPat (SigPat _ pat ty) = ppr pat <+> dcolon <+> ppr_ty where ppr_ty = case ghcPass @p of GhcPs -> ppr ty @@ -548,22 +578,37 @@ pprPat (TuplePat _ pats bx) | otherwise = tupleParens (boxityTupleSort bx) (pprWithCommas ppr pats) pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity) -pprPat (ConPatIn con details) = pprUserCon (unLoc con) details -pprPat (ConPatOut { pat_con = con - , pat_tvs = tvs - , pat_dicts = dicts - , pat_binds = binds - , pat_args = details }) - = sdocOption sdocPrintTypecheckerElaboration $ \case - False -> pprUserCon (unLoc con) details - True -> -- Tiresome; in GHC.Tc.Gen.Bind.tcRhs we print out a - -- typechecked Pat in an error message, - -- and we want to make sure it prints nicely - ppr con - <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) - , pprIfTc @p $ ppr binds ]) - <+> pprConArgs details - +pprPat (ConPat { pat_con = con + , pat_args = details + , pat_con_ext = ext + } + ) + = case ghcPass @p of + GhcPs -> pprUserCon (unLoc con) details + GhcRn -> pprUserCon (unLoc con) details + GhcTc -> sdocOption sdocPrintTypecheckerElaboration $ \case + False -> pprUserCon (unLoc con) details + True -> + -- Tiresome; in TcBinds.tcRhs we print out a typechecked Pat in an + -- error message, and we want to make sure it prints nicely + ppr con + <> braces (sep [ hsep (map pprPatBndr (tvs ++ dicts)) + , ppr binds ]) + <+> pprConArgs details + where ConPatTc { cpt_tvs = tvs + , cpt_dicts = dicts + , cpt_binds = binds + } = ext +pprPat (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> pprHsWrapper co $ \parens -> + if parens + then pprParendPat appPrec pat + else pprPat pat + where CoPat co pat _ = ext pprUserCon :: (OutputableBndr con, OutputableBndrId p) => con -> HsConPatDetails (GhcPass p) -> SDoc @@ -602,21 +647,24 @@ instance (Outputable p, Outputable arg) -} mkPrefixConPat :: DataCon -> - [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p) + [LPat GhcTc] -> [Type] -> LPat GhcTc -- Make a vanilla Prefix constructor pattern mkPrefixConPat dc pats tys - = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc) - , pat_tvs = [] - , pat_dicts = [] - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon pats - , pat_arg_tys = tys - , pat_wrap = idHsWrapper } - -mkNilPat :: Type -> OutPat (GhcPass p) + = noLoc $ ConPat { pat_con = noLoc (RealDataCon dc) + , pat_args = PrefixCon pats + , pat_con_ext = ConPatTc + { cpt_tvs = [] + , cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = tys + , cpt_wrap = idHsWrapper + } + } + +mkNilPat :: Type -> LPat GhcTc mkNilPat ty = mkPrefixConPat nilDataCon [] [ty] -mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p) +mkCharLitPat :: SourceText -> Char -> LPat GhcTc mkCharLitPat src c = mkPrefixConPat charDataCon [noLoc $ LitPat noExtField (HsCharPrim src c)] [] @@ -684,7 +732,7 @@ looksLazyPat (VarPat {}) = False looksLazyPat (WildPat {}) = False looksLazyPat _ = True -isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool +isIrrefutableHsPat :: forall p. (OutputableBndrId p) => LPat (GhcPass p) -> Bool -- (isIrrefutableHsPat p) is true if matching against p cannot fail, -- in the sense of falling through to the next pattern. -- (NB: this is not quite the same as the (silly) defn @@ -700,13 +748,14 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat (GhcPass p) -> Bool isIrrefutableHsPat = goL where + goL :: LPat (GhcPass p) -> Bool goL = go . unLoc + go :: Pat (GhcPass p) -> Bool go (WildPat {}) = True go (VarPat {}) = True go (LazyPat {}) = True go (BangPat _ pat) = goL pat - go (CoPat _ _ pat _) = go pat go (ParPat _ pat) = goL pat go (AsPat _ _ pat) = goL pat go (ViewPat _ _ pat) = goL pat @@ -716,18 +765,19 @@ isIrrefutableHsPat -- See Note [Unboxed sum patterns aren't irrefutable] go (ListPat {}) = False - go (ConPatIn {}) = False -- Conservative - go (ConPatOut - { pat_con = L _ (RealDataCon con) + go (ConPat + { pat_con = con , pat_args = details }) - = - isJust (tyConSingleDataCon_maybe (dataConTyCon con)) - -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because - -- the latter is false of existentials. See #4439 - && all goL (hsConPatArgs details) - go (ConPatOut - { pat_con = L _ (PatSynCon _pat) }) - = False -- Conservative + = case ghcPass @p of + GhcPs -> False -- Conservative + GhcRn -> False -- Conservative + GhcTc -> case con of + L _ (PatSynCon _pat) -> False -- Conservative + L _ (RealDataCon con) -> + isJust (tyConSingleDataCon_maybe (dataConTyCon con)) + -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because + -- the latter is false of existentials. See #4439 + && all goL (hsConPatArgs details) go (LitPat {}) = False go (NPat {}) = False go (NPlusKPat {}) = False @@ -736,6 +786,14 @@ isIrrefutableHsPat -- since we cannot know until the splice is evaluated. go (SplicePat {}) = False + go (XPat ext) = case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext +#endif + GhcTc -> go pat + where CoPat _ pat _ = ext + -- | Is the pattern any of combination of: -- -- - (pat) @@ -777,16 +835,21 @@ is the only thing that could possibly be matched! -- | @'patNeedsParens' p pat@ returns 'True' if the pattern @pat@ needs -- parentheses under precedence @p at . -patNeedsParens :: PprPrec -> Pat p -> Bool +patNeedsParens :: forall p. IsPass p => PprPrec -> Pat (GhcPass p) -> Bool patNeedsParens p = go where + go :: Pat (GhcPass p) -> Bool go (NPlusKPat {}) = p > opPrec go (SplicePat {}) = False - go (ConPatIn _ ds) = conPatNeedsParens p ds - go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp) + go (ConPat { pat_args = ds}) + = conPatNeedsParens p ds go (SigPat {}) = p >= sigPrec go (ViewPat {}) = True - go (CoPat _ _ p _) = go p + go (XPat ext) = case ghcPass @p of + GhcPs -> noExtCon ext + GhcRn -> noExtCon ext + GhcTc -> go inner + where CoPat _ inner _ = ext go (WildPat {}) = False go (VarPat {}) = False go (LazyPat {}) = False @@ -798,7 +861,6 @@ patNeedsParens p = go go (ListPat {}) = False go (LitPat _ l) = hsLitNeedsParens p l go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol) - go (XPat {}) = True -- conservative default -- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@ -- needs parentheses under precedence @p at . @@ -811,7 +873,10 @@ conPatNeedsParens p = go -- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and -- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat at . -parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p) +parenthesizePat :: IsPass p + => PprPrec + -> LPat (GhcPass p) + -> LPat (GhcPass p) parenthesizePat p lpat@(L loc pat) | patNeedsParens p pat = L loc (ParPat noExtField lpat) | otherwise = lpat @@ -837,12 +902,16 @@ collectEvVarsPat pat = ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p - ConPatOut {pat_dicts = dicts, pat_args = args} + ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_dicts = dicts + } + } -> unionBags (listToBag dicts) $ unionManyBags $ map collectEvVarsLPat $ hsConPatArgs args SigPat _ p _ -> collectEvVarsLPat p - CoPat _ _ p _ -> collectEvVarsPat p - ConPatIn _ _ -> panic "foldMapPatBag: ConPatIn" + XPat (CoPat _ p _) -> collectEvVarsPat p _other_pat -> emptyBag ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -24,6 +24,9 @@ just attach noSrcSpan to everything. {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -89,6 +92,7 @@ module GHC.Hs.Utils( collectPatBinders, collectPatsBinders, collectLStmtsBinders, collectStmtsBinders, collectLStmtBinders, collectStmtBinders, + CollectPass(..), hsLTyClDeclBinders, hsTyClForeignBinders, hsPatSynSelectors, getPatSynBinds, @@ -135,6 +139,7 @@ import GHC.Settings.Constants import Data.Either import Data.Function import Data.List +import Data.Proxy {- ************************************************************************ @@ -196,8 +201,11 @@ mkHsAppType e t = addCLoc e t_body (HsAppType noExtField e paren_wct) mkHsAppTypes :: LHsExpr GhcRn -> [LHsWcType GhcRn] -> LHsExpr GhcRn mkHsAppTypes = foldl' mkHsAppType -mkHsLam :: (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) => - [LPat (GhcPass p)] -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) +mkHsLam :: IsPass p + => (XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ NoExtField) + => [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) + -> LHsExpr (GhcPass p) mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam noExtField matches)) where matches = mkMatchGroup Generated @@ -230,7 +238,7 @@ mkLHsPar le@(L loc e) | hsExprNeedsParens appPrec e = L loc (HsPar noExtField le) | otherwise = le -mkParPat :: LPat (GhcPass name) -> LPat (GhcPass name) +mkParPat :: IsPass p => LPat (GhcPass p) -> LPat (GhcPass p) mkParPat lp@(L loc p) | patNeedsParens appPrec p = L loc (ParPat noExtField lp) | otherwise = lp @@ -435,25 +443,42 @@ nlConVarPatName :: Name -> [Name] -> LPat GhcRn nlConVarPatName con vars = nlConPatName con (map nlVarPat vars) nlInfixConPat :: RdrName -> LPat GhcPs -> LPat GhcPs -> LPat GhcPs -nlInfixConPat con l r = noLoc (ConPatIn (noLoc con) - (InfixCon (parenthesizePat opPrec l) - (parenthesizePat opPrec r))) +nlInfixConPat con l r = noLoc $ ConPat + { pat_con = noLoc con + , pat_args = InfixCon (parenthesizePat opPrec l) + (parenthesizePat opPrec r) + , pat_con_ext = noExtField + } nlConPat :: RdrName -> [LPat GhcPs] -> LPat GhcPs -nlConPat con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) +nlConPat con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } nlConPatName :: Name -> [LPat GhcRn] -> LPat GhcRn -nlConPatName con pats = - noLoc (ConPatIn (noLoc con) (PrefixCon (map (parenthesizePat appPrec) pats))) - -nlNullaryConPat :: IdP (GhcPass p) -> LPat (GhcPass p) -nlNullaryConPat con = noLoc (ConPatIn (noLoc con) (PrefixCon [])) +nlConPatName con pats = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon (map (parenthesizePat appPrec) pats) + } + +nlNullaryConPat :: RdrName -> LPat GhcPs +nlNullaryConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc con + , pat_args = PrefixCon [] + } nlWildConPat :: DataCon -> LPat GhcPs -nlWildConPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (PrefixCon (replicate (dataConSourceArity con) - nlWildPat))) +nlWildConPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = PrefixCon $ + replicate (dataConSourceArity con) + nlWildPat + } -- | Wildcard pattern - after parsing nlWildPat :: LPat GhcPs @@ -800,11 +825,11 @@ mkLHsCmdWrap w (L loc c) = L loc (mkHsCmdWrap w c) mkHsWrapPat :: HsWrapper -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p - | otherwise = CoPat noExtField co_fn p ty + | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc mkHsWrapPatCo co pat ty | isTcReflCo co = pat - | otherwise = CoPat noExtField (mkWpCastN co) pat ty + | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsDictLet ev_binds expr = mkLHsWrap (mkWpLet ev_binds) expr @@ -879,8 +904,10 @@ mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_strictness = NoSrcStrict } ------------ -mkMatch :: HsMatchContext (NoGhcTc (GhcPass p)) - -> [LPat (GhcPass p)] -> LHsExpr (GhcPass p) +mkMatch :: forall p. IsPass p + => HsMatchContext (NoGhcTc (GhcPass p)) + -> [LPat (GhcPass p)] + -> LHsExpr (GhcPass p) -> Located (HsLocalBinds (GhcPass p)) -> LMatch (GhcPass p) (LHsExpr (GhcPass p)) mkMatch ctxt pats expr lbinds @@ -889,6 +916,7 @@ mkMatch ctxt pats expr lbinds , m_pats = map paren pats , m_grhss = GRHSs noExtField (unguardedRHS noSrcSpan expr) lbinds }) where + paren :: Located (Pat (GhcPass p)) -> Located (Pat (GhcPass p)) paren lp@(L l p) | patNeedsParens appPrec p = L l (ParPat noExtField lp) | otherwise = lp @@ -978,49 +1006,69 @@ isBangedHsBind (PatBind {pat_lhs = pat}) isBangedHsBind _ = False -collectLocalBinders :: HsLocalBindsLR (GhcPass idL) (GhcPass idR) +collectLocalBinders :: CollectPass (GhcPass idL) + => HsLocalBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collectLocalBinders (HsValBinds _ binds) = collectHsIdBinders binds -- No pattern synonyms here collectLocalBinders (HsIPBinds {}) = [] collectLocalBinders (EmptyLocalBinds _) = [] -collectHsIdBinders, collectHsValBinders - :: HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] +collectHsIdBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] -- ^ Collect 'Id' binders only, or 'Id's + pattern synonyms, respectively collectHsIdBinders = collect_hs_val_binders True + +collectHsValBinders :: CollectPass (GhcPass idL) + => HsValBindsLR (GhcPass idL) (GhcPass idR) + -> [IdP (GhcPass idL)] collectHsValBinders = collect_hs_val_binders False -collectHsBindBinders :: XRec pass Pat ~ Located (Pat pass) => - HsBindLR pass idR -> [IdP pass] +collectHsBindBinders :: CollectPass p + => HsBindLR p idR + -> [IdP p] -- ^ Collect both 'Id's and pattern-synonym binders collectHsBindBinders b = collect_bind False b [] -collectHsBindsBinders :: LHsBindsLR (GhcPass p) idR -> [IdP (GhcPass p)] +collectHsBindsBinders :: CollectPass p + => LHsBindsLR p idR + -> [IdP p] collectHsBindsBinders binds = collect_binds False binds [] -collectHsBindListBinders :: [LHsBindLR (GhcPass p) idR] -> [IdP (GhcPass p)] +collectHsBindListBinders :: CollectPass p + => [LHsBindLR p idR] + -> [IdP p] -- ^ Same as 'collectHsBindsBinders', but works over a list of bindings collectHsBindListBinders = foldr (collect_bind False . unLoc) [] -collect_hs_val_binders :: Bool -> HsValBindsLR (GhcPass idL) (GhcPass idR) +collect_hs_val_binders :: CollectPass (GhcPass idL) + => Bool + -> HsValBindsLR (GhcPass idL) (GhcPass idR) -> [IdP (GhcPass idL)] collect_hs_val_binders ps (ValBinds _ binds _) = collect_binds ps binds [] collect_hs_val_binders ps (XValBindsLR (NValBinds binds _)) = collect_out_binds ps binds -collect_out_binds :: Bool -> [(RecFlag, LHsBinds (GhcPass p))] -> - [IdP (GhcPass p)] +collect_out_binds :: CollectPass p + => Bool + -> [(RecFlag, LHsBinds p)] + -> [IdP p] collect_out_binds ps = foldr (collect_binds ps . snd) [] -collect_binds :: Bool -> LHsBindsLR (GhcPass p) idR -> - [IdP (GhcPass p)] -> [IdP (GhcPass p)] +collect_binds :: CollectPass p + => Bool + -> LHsBindsLR p idR + -> [IdP p] + -> [IdP p] -- ^ Collect 'Id's, or 'Id's + pattern synonyms, depending on boolean flag collect_binds ps binds acc = foldr (collect_bind ps . unLoc) acc binds -collect_bind :: XRec pass Pat ~ Located (Pat pass) => - Bool -> HsBindLR pass idR -> - [IdP pass] -> [IdP pass] +collect_bind :: CollectPass p + => Bool + -> HsBindLR p idR + -> [IdP p] + -> [IdP p] collect_bind _ (PatBind { pat_lhs = p }) acc = collect_lpat p acc collect_bind _ (FunBind { fun_id = L _ f }) acc = f : acc collect_bind _ (VarBind { var_id = f }) acc = f : acc @@ -1044,19 +1092,23 @@ collectMethodBinders binds = foldr (get . unLoc) [] binds -- Someone else complains about non-FunBinds ----------------- Statements -------------------------- -collectLStmtsBinders :: [LStmtLR (GhcPass idL) (GhcPass idR) body] +collectLStmtsBinders :: (CollectPass (GhcPass idL)) + => [LStmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectLStmtsBinders = concatMap collectLStmtBinders -collectStmtsBinders :: [StmtLR (GhcPass idL) (GhcPass idR) body] +collectStmtsBinders :: (CollectPass (GhcPass idL)) + => [StmtLR (GhcPass idL) (GhcPass idR) body] -> [IdP (GhcPass idL)] collectStmtsBinders = concatMap collectStmtBinders -collectLStmtBinders :: LStmtLR (GhcPass idL) (GhcPass idR) body +collectLStmtBinders :: (CollectPass (GhcPass idL)) + => LStmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] collectLStmtBinders = collectStmtBinders . unLoc -collectStmtBinders :: StmtLR (GhcPass idL) (GhcPass idR) body +collectStmtBinders :: (CollectPass (GhcPass idL)) + => StmtLR (GhcPass idL) (GhcPass idR) body -> [IdP (GhcPass idL)] -- Id Binders for a Stmt... [but what about pattern-sig type vars]? collectStmtBinders (BindStmt _ pat _) = collectPatBinders pat @@ -1071,47 +1123,65 @@ collectStmtBinders (ApplicativeStmt _ args _) = concatMap collectArgBinders args where collectArgBinders (_, ApplicativeArgOne { app_arg_pattern = pat }) = collectPatBinders pat collectArgBinders (_, ApplicativeArgMany { bv_pattern = pat }) = collectPatBinders pat + collectArgBinders (_, XApplicativeArg {}) = [] ----------------- Patterns -------------------------- -collectPatBinders :: LPat (GhcPass p) -> [IdP (GhcPass p)] +collectPatBinders :: CollectPass p => LPat p -> [IdP p] collectPatBinders pat = collect_lpat pat [] -collectPatsBinders :: [LPat (GhcPass p)] -> [IdP (GhcPass p)] +collectPatsBinders :: CollectPass p => [LPat p] -> [IdP p] collectPatsBinders pats = foldr collect_lpat [] pats ------------- -collect_lpat :: XRec pass Pat ~ Located (Pat pass) => - LPat pass -> [IdP pass] -> [IdP pass] -collect_lpat p bndrs - = go (unLoc p) - where - go (VarPat _ var) = unLoc var : bndrs - go (WildPat _) = bndrs - go (LazyPat _ pat) = collect_lpat pat bndrs - go (BangPat _ pat) = collect_lpat pat bndrs - go (AsPat _ a pat) = unLoc a : collect_lpat pat bndrs - go (ViewPat _ _ pat) = collect_lpat pat bndrs - go (ParPat _ pat) = collect_lpat pat bndrs - - go (ListPat _ pats) = foldr collect_lpat bndrs pats - go (TuplePat _ pats _) = foldr collect_lpat bndrs pats - go (SumPat _ pat _ _) = collect_lpat pat bndrs - - go (ConPatIn _ ps) = foldr collect_lpat bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps}) = foldr collect_lpat bndrs (hsConPatArgs ps) - -- See Note [Dictionary binders in ConPatOut] - go (LitPat _ _) = bndrs - go (NPat {}) = bndrs - go (NPlusKPat _ n _ _ _ _) = unLoc n : bndrs - - go (SigPat _ pat _) = collect_lpat pat bndrs - - go (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) - = go pat - go (SplicePat _ _) = bndrs - go (CoPat _ _ pat _) = go pat - go (XPat {}) = bndrs +collect_lpat :: forall pass. (CollectPass pass) + => LPat pass -> [IdP pass] -> [IdP pass] +collect_lpat p bndrs = collect_pat (unLoc p) bndrs + +collect_pat :: forall p. CollectPass p + => Pat p + -> [IdP p] + -> [IdP p] +collect_pat pat bndrs = case pat of + (VarPat _ var) -> unLoc var : bndrs + (WildPat _) -> bndrs + (LazyPat _ pat) -> collect_lpat pat bndrs + (BangPat _ pat) -> collect_lpat pat bndrs + (AsPat _ a pat) -> unLoc a : collect_lpat pat bndrs + (ViewPat _ _ pat) -> collect_lpat pat bndrs + (ParPat _ pat) -> collect_lpat pat bndrs + (ListPat _ pats) -> foldr collect_lpat bndrs pats + (TuplePat _ pats _) -> foldr collect_lpat bndrs pats + (SumPat _ pat _ _) -> collect_lpat pat bndrs + (ConPat {pat_args=ps}) -> foldr collect_lpat bndrs (hsConPatArgs ps) + -- See Note [Dictionary binders in ConPatOut] + (LitPat _ _) -> bndrs + (NPat {}) -> bndrs + (NPlusKPat _ n _ _ _ _) -> unLoc n : bndrs + (SigPat _ pat _) -> collect_lpat pat bndrs + (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) + -> collect_pat pat bndrs + (SplicePat _ _) -> bndrs + (XPat ext) -> collectXXPat (Proxy @p) ext bndrs + +-- | This class specifies how to collect variable identifiers from extension patterns in the given pass. +-- Consumers of the GHC API that define their own passes should feel free to implement instances in order +-- to make use of functions which depend on it. +-- +-- In particular, Haddock already makes use of this, with an instance for its 'DocNameI' pass so that +-- it can reuse the code in GHC for collecting binders. +class (XRec p Pat ~ Located (Pat p)) => CollectPass p where + collectXXPat :: Proxy p -> XXPat p -> [IdP p] -> [IdP p] + +instance CollectPass (GhcPass 'Parsed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Renamed) where + collectXXPat _ ext = noExtCon ext + +instance CollectPass (GhcPass 'Typechecked) where + collectXXPat _ (CoPat _ pat _) = collect_pat pat + {- Note [Dictionary binders in ConPatOut] See also same Note in GHC.HsToCore.Arrows @@ -1393,10 +1463,8 @@ lPatImplicits = hs_lpat hs_pat (TuplePat _ pats _) = hs_lpats pats hs_pat (SigPat _ pat _) = hs_lpat pat - hs_pat (CoPat _ _ pat _) = hs_pat pat - hs_pat (ConPatIn n ps) = details n ps - hs_pat (ConPatOut {pat_con=con, pat_args=ps}) = details (fmap conLikeName con) ps + hs_pat (ConPat {pat_con=con, pat_args=ps}) = details con ps hs_pat _ = [] ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -1191,7 +1191,7 @@ Note [Dictionary binders in ConPatOut] See also same Note in GHC.Hs.Utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following functions to collect value variables from patterns are copied from GHC.Hs.Utils, with one change: we also collect the dictionary -bindings (pat_binds) from ConPatOut. We need them for cases like +bindings (cpt_binds) from ConPatOut. We need them for cases like h :: Arrow a => Int -> a (Int,Int) Int h x = proc (y,z) -> case compare x y of @@ -1231,8 +1231,8 @@ collectl (L _ pat) bndrs go (TuplePat _ pats _) = foldr collectl bndrs pats go (SumPat _ pat _ _) = collectl pat bndrs - go (ConPatIn _ ps) = foldr collectl bndrs (hsConPatArgs ps) - go (ConPatOut {pat_args=ps, pat_binds=ds}) = + go (ConPat { pat_args = ps + , pat_con_ext = ConPatTc { cpt_binds = ds }}) = collectEvBinders ds ++ foldr collectl bndrs (hsConPatArgs ps) go (LitPat _ _) = bndrs @@ -1240,7 +1240,7 @@ collectl (L _ pat) bndrs go (NPlusKPat _ (L _ n) _ _ _ _) = n : bndrs go (SigPat _ pat _) = collectl pat bndrs - go (CoPat _ _ pat _) = collectl (noLoc pat) bndrs + go (XPat (CoPat _ pat _)) = collectl (noLoc pat) bndrs go (ViewPat _ _ pat) = collectl pat bndrs go p@(SplicePat {}) = pprPanic "collectl/go" (ppr p) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -117,7 +117,9 @@ user-written. This lets us relate Names (from ClsInsts) to comments (associated with InstDecls and DerivDecls). -} -getMainDeclBinder :: HsDecl (GhcPass p) -> [IdP (GhcPass p)] +getMainDeclBinder :: (CollectPass (GhcPass p)) + => HsDecl (GhcPass p) + -> [IdP (GhcPass p)] getMainDeclBinder (TyClD _ d) = [tcdName d] getMainDeclBinder (ValD _ d) = case collectHsBindBinders d of ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -697,13 +697,16 @@ dsExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = fields req_wrap = dict_req_wrap <.> mkWpTyApps in_inst_tys - pat = noLoc $ ConPatOut { pat_con = noLoc con - , pat_tvs = ex_tvs - , pat_dicts = eqs_vars ++ theta_vars - , pat_binds = emptyTcEvBinds - , pat_args = PrefixCon $ map nlVarPat arg_ids - , pat_arg_tys = in_inst_tys - , pat_wrap = req_wrap } + pat = noLoc $ ConPat { pat_con = noLoc con + , pat_args = PrefixCon $ map nlVarPat arg_ids + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs + , cpt_dicts = eqs_vars ++ theta_vars + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = in_inst_tys + , cpt_wrap = req_wrap + } + } ; return (mkSimpleMatch RecUpd [pat] wrapped_rhs) } {- Note [Scrutinee in Record updates] ===================================== compiler/GHC/HsToCore/ListComp.hs ===================================== @@ -266,7 +266,7 @@ deListComp (RecStmt {} : _) _ = panic "deListComp RecStmt" deListComp (ApplicativeStmt {} : _) _ = panic "deListComp ApplicativeStmt" -deBindComp :: OutPat GhcTc +deBindComp :: LPat GhcTc -> CoreExpr -> [ExprStmt GhcTc] -> CoreExpr ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -268,7 +268,7 @@ matchBangs (var :| vars) ty eqns matchCoercion :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr) -- Apply the coercion to the match variable and then match that matchCoercion (var :| vars) ty (eqns@(eqn1 :| _)) - = do { let CoPat _ co pat _ = firstPat eqn1 + = do { let XPat (CoPat co pat _) = firstPat eqn1 ; let pat_ty' = hsPatType pat ; var' <- newUniqueId var pat_ty' ; match_result <- match (var':vars) ty $ NEL.toList $ @@ -314,7 +314,7 @@ decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats })) decomposeFirstPat _ _ = panic "decomposeFirstPat" getCoPat, getBangPat, getViewPat, getOLPat :: Pat GhcTc -> Pat GhcTc -getCoPat (CoPat _ _ pat _) = pat +getCoPat (XPat (CoPat _ pat _)) = pat getCoPat _ = panic "getCoPat" getBangPat (BangPat _ pat ) = unLoc pat getBangPat _ = panic "getBangPat" @@ -513,8 +513,8 @@ tidy_bang_pat v o _ (SigPat _ (L l p) _) = tidy_bang_pat v o l p -- it may disappear next time tidy_bang_pat v o l (AsPat x v' p) = tidy1 v o (AsPat x v' (L l (BangPat noExtField p))) -tidy_bang_pat v o l (CoPat x w p t) - = tidy1 v o (CoPat x w (BangPat noExtField (L l p)) t) +tidy_bang_pat v o l (XPat (CoPat w p t)) + = tidy1 v o (XPat $ CoPat w (BangPat noExtField (L l p)) t) -- Discard bang around strict pattern tidy_bang_pat v o _ p@(LitPat {}) = tidy1 v o p @@ -523,9 +523,12 @@ tidy_bang_pat v o _ p@(TuplePat {}) = tidy1 v o p tidy_bang_pat v o _ p@(SumPat {}) = tidy1 v o p -- Data/newtype constructors -tidy_bang_pat v o l p@(ConPatOut { pat_con = L _ (RealDataCon dc) - , pat_args = args - , pat_arg_tys = arg_tys }) +tidy_bang_pat v o l p@(ConPat { pat_con = L _ (RealDataCon dc) + , pat_args = args + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + } + }) -- Newtypes: push bang inwards (#9844) = if isNewTyCon (dataConTyCon dc) @@ -1119,8 +1122,9 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2 eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys patGroup :: Platform -> Pat GhcTc -> PatGroup -patGroup _ (ConPatOut { pat_con = L _ con - , pat_arg_tys = tys }) +patGroup _ (ConPat { pat_con = L _ con + , pat_con_ext = ConPatTc { cpt_arg_tys = tys } + }) | RealDataCon dcon <- con = PgCon dcon | PatSynCon psyn <- con = PgSyn psyn tys patGroup _ (WildPat {}) = PgAny @@ -1137,7 +1141,7 @@ patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) = case oval of HsIntegral i -> PgNpK (il_value i) _ -> pprPanic "patGroup NPlusKPat" (ppr oval) -patGroup _ (CoPat _ _ p _) = PgCo (hsPatType p) +patGroup _ (XPat (CoPat _ p _)) = PgCo (hsPatType p) -- Type of innelexp pattern patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p)) patGroup _ (ListPat (ListPatTc _ (Just _)) _) = PgOverloadedList ===================================== compiler/GHC/HsToCore/Match/Constructor.hs ===================================== @@ -145,9 +145,16 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor ; return $ foldr1 (.) wraps <$> match_result } - shift (_, eqn@(EqnInfo { eqn_pats = ConPatOut{ pat_tvs = tvs, pat_dicts = ds, - pat_binds = bind, pat_args = args - } : pats })) + shift (_, eqn@(EqnInfo + { eqn_pats = ConPat + { pat_args = args + , pat_con_ext = ConPatTc + { cpt_tvs = tvs + , cpt_dicts = ds + , cpt_binds = bind + } + } : pats + })) = do ds_bind <- dsTcEvBinds bind return ( wrapBinds (tvs `zip` tvs1) . wrapBinds (ds `zip` dicts1) @@ -173,10 +180,15 @@ matchOneConLike vars ty (eqn1 :| eqns) -- All eqns for a single constructor alt_wrapper = wrapper1, alt_result = foldr1 combineMatchResults match_results } } where - ConPatOut { pat_con = L _ con1 - , pat_arg_tys = arg_tys, pat_wrap = wrapper1, - pat_tvs = tvs1, pat_dicts = dicts1, pat_args = args1 } - = firstPat eqn1 + ConPat { pat_con = L _ con1 + , pat_args = args1 + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_wrap = wrapper1 + , cpt_tvs = tvs1 + , cpt_dicts = dicts1 + } + } = firstPat eqn1 fields1 = map flSelector (conLikeFieldLabels con1) ex_tvs = conLikeExTyCoVars con1 ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -443,7 +443,7 @@ translatePat fam_insts x pat = case pat of -- See Note [Translate CoPats] -- Generally the translation is -- pat |> co ===> let y = x |> co, pat <- y where y is a match var of pat - CoPat _ wrapper p _ty + XPat (CoPat wrapper p _ty) | isIdHsWrapper wrapper -> translatePat fam_insts x p | WpCast co <- wrapper, isReflexiveCo co -> translatePat fam_insts x p | otherwise -> do @@ -498,11 +498,14 @@ translatePat fam_insts x pat = case pat of -- -- See #14547, especially comment#9 and comment#10. - ConPatOut { pat_con = L _ con - , pat_arg_tys = arg_tys - , pat_tvs = ex_tvs - , pat_dicts = dicts - , pat_args = ps } -> do + ConPat { pat_con = L _ con + , pat_args = ps + , pat_con_ext = ConPatTc + { cpt_arg_tys = arg_tys + , cpt_tvs = ex_tvs + , cpt_dicts = dicts + } + } -> do translateConPatOut fam_insts x con arg_tys ex_tvs dicts ps NPat ty (L _ olit) mb_neg _ -> do @@ -544,7 +547,6 @@ translatePat fam_insts x pat = case pat of -- -------------------------------------------------------------------------- -- Not supposed to happen - ConPatIn {} -> panic "Check.translatePat: ConPatIn" SplicePat {} -> panic "Check.translatePat: SplicePat" -- | 'translatePat', but also select and return a new match var. ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1914,7 +1914,7 @@ repP (TuplePat _ ps boxed) | otherwise = do { qs <- repLPs ps; repPunboxedTup qs } repP (SumPat _ p alt arity) = do { p1 <- repLP p ; repPunboxedSum p1 alt arity } -repP (ConPatIn dc details) +repP (ConPat NoExtField dc details) = do { con_str <- lookupLOcc dc ; case details of PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs } ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -716,14 +716,14 @@ strip_bangs (L _ (ParPat _ p)) = strip_bangs p strip_bangs (L _ (BangPat _ p)) = strip_bangs p strip_bangs lp = lp -is_flat_prod_lpat :: LPat (GhcPass p) -> Bool +is_flat_prod_lpat :: LPat GhcTc -> Bool is_flat_prod_lpat = is_flat_prod_pat . unLoc -is_flat_prod_pat :: Pat (GhcPass p) -> Bool +is_flat_prod_pat :: Pat GhcTc -> Bool is_flat_prod_pat (ParPat _ p) = is_flat_prod_lpat p is_flat_prod_pat (TuplePat _ ps Boxed) = all is_triv_lpat ps -is_flat_prod_pat (ConPatOut { pat_con = L _ pcon - , pat_args = ps}) +is_flat_prod_pat (ConPat { pat_con = L _ pcon + , pat_args = ps}) | RealDataCon con <- pcon , isProductTyCon (dataConTyCon con) = all is_triv_lpat (hsConPatArgs ps) @@ -753,7 +753,7 @@ mkLHsPatTup [lpat] = lpat mkLHsPatTup lpats = L (getLoc (head lpats)) $ mkVanillaTuplePat lpats Boxed -mkVanillaTuplePat :: [OutPat GhcTc] -> Boxity -> Pat GhcTc +mkVanillaTuplePat :: [LPat GhcTc] -> Boxity -> Pat GhcTc -- A vanilla tuple pattern simply gets its type from its sub-patterns mkVanillaTuplePat pats box = TuplePat (map hsLPatType pats) pats box ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -765,6 +765,7 @@ instance ( ToHie (HsMatchContext a) toHie _ = pure [] instance ( a ~ GhcPass p + , IsPass p , ToHie (Context (Located (IdP a))) , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) @@ -807,12 +808,11 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPatIn c dets -> - [ toHie $ C Use c - , toHie $ contextify dets - ] - ConPatOut {pat_con = con, pat_args = dets}-> - [ toHie $ C Use $ fmap conLikeName con + ConPat {pat_con = con, pat_args = dets}-> + [ case ghcPass @p of + GhcPs -> toHie $ C Use $ con + GhcRn -> toHie $ C Use $ con + GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets ] ViewPat _ expr pat -> @@ -836,8 +836,15 @@ instance ( a ~ GhcPass p (protectSig @a cscope sig) -- See Note [Scoping Rules for SigPat] ] - CoPat _ _ _ _ -> - [] + XPat e -> case ghcPass @p of +#if __GLASGOW_HASKELL__ < 811 + GhcPs -> noExtCon e + GhcRn -> noExtCon e +#endif + GhcTc -> [] + where + -- Make sure we get an error if this changes + _noWarn@(CoPat _ _ _) = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -603,7 +603,7 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) = ; return $ mkMatchGroup FromSource matches } where fromDecl (L loc decl@(ValD _ (PatBind _ - pat@(L _ (ConPatIn ln@(L _ name) details)) + pat@(L _ (ConPat NoExtField ln@(L _ name) details)) rhs _))) = do { unless (name == patsyn_name) $ wrongNameBindingErr loc decl @@ -1077,7 +1077,11 @@ checkLPat e@(L l _) = checkPat l e [] checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs] -> PV (LPat GhcPs) checkPat loc (L l e@(PatBuilderVar (L _ c))) args - | isRdrDataCon c = return (L loc (ConPatIn (L l c) (PrefixCon args))) + | isRdrDataCon c = return . L loc $ ConPat + { pat_con_ext = noExtField + , pat_con = L l c + , pat_args = PrefixCon args + } | not (null args) && patIsRec c = localPV_msg (\_ -> text "Perhaps you intended to use RecursiveDo") $ patFail l (ppr e) @@ -1114,7 +1118,11 @@ checkAPat loc e0 = do | isRdrDataCon c -> do l <- checkLPat l r <- checkLPat r - return (ConPatIn (L cl c) (InfixCon l r)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = L cl c + , pat_args = InfixCon l r + } PatBuilderPar e -> checkLPat e >>= (return . (ParPat noExtField)) _ -> patFail loc (ppr e0) @@ -2065,7 +2073,11 @@ mkPatRec :: mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) | isRdrDataCon (unLoc c) = do fs <- mapM checkPatField fs - return (PatBuilderPat (ConPatIn c (RecCon (HsRecFields fs dd)))) + return $ PatBuilderPat $ ConPat + { pat_con_ext = noExtField + , pat_con = c + , pat_args = RecCon (HsRecFields fs dd) + } mkPatRec p _ = addFatalError (getLoc p) $ text "Not a record constructor:" <+> ppr p ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -12,6 +12,7 @@ free variables. {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -1823,13 +1824,12 @@ isStrictPattern lpat = ListPat{} -> True TuplePat{} -> True SumPat{} -> True - ConPatIn{} -> True - ConPatOut{} -> True + ConPat{} -> True LitPat{} -> True NPat{} -> True NPlusKPat{} -> True SplicePat{} -> True - CoPat{} -> panic "isStrictPattern: CoPat" + XPat{} -> panic "isStrictPattern: XPat" {- Note [ApplicativeDo and refutable patterns] ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1221,28 +1221,47 @@ mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment mkConOpPatRn :: Located Name -> Fixity -> LPat GhcRn -> LPat GhcRn -> RnM (Pat GhcRn) -mkConOpPatRn op2 fix2 p1@(L loc (ConPatIn op1 (InfixCon p11 p12))) p2 +mkConOpPatRn op2 fix2 p1@(L loc (ConPat NoExtField op1 (InfixCon p11 p12))) p2 = do { fix1 <- lookupFixityRn (unLoc op1) ; let (nofix_error, associate_right) = compareFixity fix1 fix2 ; if nofix_error then do { precParseErr (NormalOp (unLoc op1),fix1) (NormalOp (unLoc op2),fix2) - ; return (ConPatIn op2 (InfixCon p1 p2)) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } else if associate_right then do { new_p <- mkConOpPatRn op2 fix2 p12 p2 - ; return (ConPatIn op1 (InfixCon p11 (L loc new_p))) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op1 + , pat_args = InfixCon p11 (L loc new_p) + } + } -- XXX loc right? - else return (ConPatIn op2 (InfixCon p1 p2)) } + else return $ ConPat + { pat_con_ext = noExtField + , pat_con = op2 + , pat_args = InfixCon p1 p2 + } + } mkConOpPatRn op _ p1 p2 -- Default case, no rearrangment = ASSERT( not_op_pat (unLoc p2) ) - return (ConPatIn op (InfixCon p1 p2)) + return $ ConPat + { pat_con_ext = noExtField + , pat_con = op + , pat_args = InfixCon p1 p2 + } not_op_pat :: Pat GhcRn -> Bool -not_op_pat (ConPatIn _ (InfixCon _ _)) = False -not_op_pat _ = True +not_op_pat (ConPat NoExtField _ (InfixCon _ _)) = False +not_op_pat _ = True -------------------------------------- checkPrecMatch :: Name -> MatchGroup GhcRn body -> RnM () @@ -1270,7 +1289,7 @@ checkPrecMatch op (MG { mg_alts = (L _ ms) }) -- second eqn. checkPrec :: Name -> Pat GhcRn -> Bool -> IOEnv (Env TcGblEnv TcLclEnv) () -checkPrec op (ConPatIn op1 (InfixCon _ _)) right = do +checkPrec op (ConPat NoExtField op1 (InfixCon _ _)) right = do op_fix@(Fixity _ op_prec op_dir) <- lookupFixityRn op op1_fix@(Fixity _ op1_prec op1_dir) <- lookupFixityRn (unLoc op1) let ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -468,14 +468,14 @@ rnPatAndThen mk p@(ViewPat x expr pat) -- ; return (ViewPat expr' pat' ty) } ; return (ViewPat x expr' pat') } -rnPatAndThen mk (ConPatIn con stuff) +rnPatAndThen mk (ConPat NoExtField con args) -- rnConPatAndThen takes care of reconstructing the pattern -- The pattern for the empty list needs to be replaced by an empty explicit list pattern when overloaded lists is turned on. = case unLoc con == nameRdrName (dataConName nilDataCon) of True -> do { ol_flag <- liftCps $ xoptM LangExt.OverloadedLists ; if ol_flag then rnPatAndThen mk (ListPat noExtField []) - else rnConPatAndThen mk con stuff} - False -> rnConPatAndThen mk con stuff + else rnConPatAndThen mk con args} + False -> rnConPatAndThen mk con args rnPatAndThen mk (ListPat _ pats) = do { opt_OverloadedLists <- liftCps $ xoptM LangExt.OverloadedLists @@ -505,9 +505,6 @@ rnPatAndThen mk (SplicePat _ splice) Left not_yet_renamed -> rnPatAndThen mk not_yet_renamed Right already_renamed -> return already_renamed } -rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat) - - -------------------- rnConPatAndThen :: NameMaker -> Located RdrName -- the constructor @@ -517,7 +514,12 @@ rnConPatAndThen :: NameMaker rnConPatAndThen mk con (PrefixCon pats) = do { con' <- lookupConCps con ; pats' <- rnLPatsAndThen mk pats - ; return (ConPatIn con' (PrefixCon pats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = PrefixCon pats' + } + } rnConPatAndThen mk con (InfixCon pat1 pat2) = do { con' <- lookupConCps con @@ -529,7 +531,12 @@ rnConPatAndThen mk con (InfixCon pat1 pat2) rnConPatAndThen mk con (RecCon rpats) = do { con' <- lookupConCps con ; rpats' <- rnHsRecPatsAndThen mk con' rpats - ; return (ConPatIn con' (RecCon rpats')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = con' + , pat_args = RecCon rpats' + } + } checkUnusedRecordWildcardCps :: SrcSpan -> Maybe [Name] -> CpsRn () checkUnusedRecordWildcardCps loc dotdot_names = ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -532,9 +532,13 @@ unliftedCompare lt_op eq_op a_expr b_expr lt eq gt nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {}) -nlConWildPat con = noLoc (ConPatIn (noLoc (getRdrName con)) - (RecCon (HsRecFields { rec_flds = [] - , rec_dotdot = Nothing }))) +nlConWildPat con = noLoc $ ConPat + { pat_con_ext = noExtField + , pat_con = noLoc $ getRdrName con + , pat_args = RecCon $ HsRecFields + { rec_flds = [] + , rec_dotdot = Nothing } + } {- ************************************************************************ ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -81,9 +81,9 @@ Note that ************************************************************************ -} -tcProc :: InPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr +tcProc :: LPat GhcRn -> LHsCmdTop GhcRn -- proc pat -> expr -> ExpRhoType -- Expected type of whole proc expression - -> TcM (OutPat GhcTcId, LHsCmdTop GhcTcId, TcCoercion) + -> TcM (LPat GhcTc, LHsCmdTop GhcTcId, TcCoercion) tcProc pat cmd exp_ty = newArrowScope $ ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -506,8 +506,8 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside tcPolyBinds sig_fn prag_fn Recursive rec_tc closed binds recursivePatSynErr :: - OutputableBndrId p => - SrcSpan -- ^ The location of the first pattern synonym binding + (OutputableBndrId p, CollectPass (GhcPass p)) + => SrcSpan -- ^ The location of the first pattern synonym binding -- (for error reporting) -> LHsBinds (GhcPass p) -> TcM a ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -521,7 +521,7 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPatIn con arg_pats) pat_ty thing_inside +tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside = tcConPat penv con pat_ty arg_pats thing_inside ------------------------ @@ -872,12 +872,15 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = [], pat_dicts = [], - pat_binds = emptyTcEvBinds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = [], cpt_dicts = [] + , cpt_binds = emptyTcEvBinds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } @@ -906,13 +909,17 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty <- checkConstraints skol_info ex_tvs' given $ tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside - ; let res_pat = ConPatOut { pat_con = header, - pat_tvs = ex_tvs', - pat_dicts = given, - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = ctxt_res_tys, - pat_wrap = idHsWrapper } + ; let res_pat = ConPat + { pat_con = header + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = given + , cpt_binds = ev_binds + , cpt_arg_tys = ctxt_res_tys + , cpt_wrap = idHsWrapper + } + } ; return (mkHsWrapPat wrap res_pat pat_ty, res) } } @@ -957,13 +964,16 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) - ; let res_pat = ConPatOut { pat_con = L con_span $ PatSynCon pat_syn, - pat_tvs = ex_tvs', - pat_dicts = prov_dicts', - pat_binds = ev_binds, - pat_args = arg_pats', - pat_arg_tys = mkTyVarTys univ_tvs', - pat_wrap = req_wrap } + ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn + , pat_args = arg_pats' + , pat_con_ext = ConPatTc + { cpt_tvs = ex_tvs' + , cpt_dicts = prov_dicts' + , cpt_binds = ev_binds + , cpt_arg_tys = mkTyVarTys univ_tvs' + , cpt_wrap = req_wrap + } + } ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap res_pat pat_ty, res) } ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2178,9 +2178,9 @@ tcDefaultAssocDecl fam_tc , text "pats" <+> ppr pats , text "rhs_ty" <+> ppr rhs_ty ]) - ; pat_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis - ; check_all_distinct_tvs ppr_eqn $ zip pat_tvs pats_vis - ; let subst = zipTvSubst pat_tvs (mkTyVarTys fam_tvs) + ; cpt_tvs <- zipWithM (extract_tv ppr_eqn) pats pats_vis + ; check_all_distinct_tvs ppr_eqn $ zip cpt_tvs pats_vis + ; let subst = zipTvSubst cpt_tvs (mkTyVarTys fam_tvs) ; pure $ Just (substTyUnchecked subst rhs_ty, loc) -- We also perform other checks for well-formedness and validity -- later, in checkValidClass @@ -2217,8 +2217,8 @@ tcDefaultAssocDecl fam_tc -- visibilities (the latter are only used for error -- message purposes) -> TcM () - check_all_distinct_tvs ppr_eqn pat_tvs_vis = - let dups = findDupsEq ((==) `on` fst) pat_tvs_vis in + check_all_distinct_tvs ppr_eqn cpt_tvs_vis = + let dups = findDupsEq ((==) `on` fst) cpt_tvs_vis in traverse_ (\d -> let (pat_tv, pat_vis) = NE.head d in failWithTc $ pprWithExplicitKindsWhen (isInvisibleArgFlag pat_vis) $ ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -940,7 +940,7 @@ tcPatToExpr name args pat = go pat go (L loc p) = L loc <$> go1 p go1 :: Pat GhcRn -> Either MsgDoc (HsExpr GhcRn) - go1 (ConPatIn con info) + go1 (ConPat NoExtField con info) = case info of PrefixCon ps -> mkPrefixConExpr con ps InfixCon l r -> mkPrefixConExpr con [l,r] @@ -973,8 +973,6 @@ tcPatToExpr name args pat = go pat = return $ unLoc $ foldl' nlHsApp (noLoc neg) [noLoc (HsOverLit noExtField n)] | otherwise = return $ HsOverLit noExtField n - go1 (ConPatOut{}) = panic "ConPatOut in output of renamer" - go1 (CoPat{}) = panic "CoPat in output of renamer" go1 (SplicePat _ (HsSpliced _ _ (HsSplicedPat pat))) = go1 pat go1 (SplicePat _ (HsSpliced{})) = panic "Invalid splice variety" @@ -1124,10 +1122,11 @@ tcCollectEx pat = go pat go1 (TuplePat _ ps _) = mergeMany . map go $ ps go1 (SumPat _ p _ _) = go p go1 (ViewPat _ _ p) = go p - go1 con at ConPatOut{} = merge (pat_tvs con, pat_dicts con) $ + go1 con at ConPat{ pat_con_ext = con' } + = merge (cpt_tvs con', cpt_dicts con') $ goConDetails $ pat_args con go1 (SigPat _ p _) = go p - go1 (CoPat _ _ p _) = go1 p + go1 (XPat (CoPat _ p _)) = go1 p go1 (NPlusKPat _ n k _ geq subtract) = pprPanic "TODO: NPlusKPat" $ ppr n $$ ppr k $$ ppr geq $$ ppr subtract go1 _ = empty ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -895,7 +895,7 @@ mkOneRecordSelector all_cons idDetails fl mk_match con = mkSimpleMatch (mkPrefixFunRhs sel_lname) [L loc (mk_sel_pat con)] (L loc (HsVar noExtField (L loc field_var))) - mk_sel_pat con = ConPatIn (L loc (getName con)) (RecCon rec_fields) + mk_sel_pat con = ConPat NoExtField (L loc (getName con)) (RecCon rec_fields) rec_fields = HsRecFields { rec_flds = [rec_field], rec_dotdot = Nothing } rec_field = noLoc (HsRecField { hsRecFieldLbl ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -114,14 +114,16 @@ hsPatType (ListPat (ListPatTc _ (Just (ty,_))) _) = ty hsPatType (TuplePat tys _ bx) = mkTupleTy1 bx tys -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make hsPatType (SumPat tys _ _ _ ) = mkSumTy tys -hsPatType (ConPatOut { pat_con = lcon - , pat_arg_tys = tys }) +hsPatType (ConPat { pat_con = lcon + , pat_con_ext = ConPatTc + { cpt_arg_tys = tys + } + }) = conLikeResTy (unLoc lcon) tys hsPatType (SigPat ty _ _) = ty hsPatType (NPat ty _ _ _) = ty hsPatType (NPlusKPat ty _ _ _ _ _) = ty -hsPatType (CoPat _ _ _ ty) = ty -hsPatType ConPatIn{} = panic "hsPatType: ConPatIn" +hsPatType (XPat (CoPat _ _ ty)) = ty hsPatType SplicePat{} = panic "hsPatType: SplicePat" hsLitType :: HsLit (GhcPass p) -> TcType @@ -1296,7 +1298,7 @@ mapIPNameTc f (Right x) = do r <- f x ************************************************************************ -} -zonkPat :: ZonkEnv -> OutPat GhcTcId -> TcM (ZonkEnv, OutPat GhcTc) +zonkPat :: ZonkEnv -> LPat GhcTc -> TcM (ZonkEnv, LPat GhcTc) -- Extend the environment as we go, because it's possible for one -- pattern to bind something that is used in another (inside or -- to the right) @@ -1358,13 +1360,16 @@ zonk_pat env (SumPat tys pat alt arity ) ; (env', pat') <- zonkPat env pat ; return (env', SumPat tys' pat' alt arity) } -zonk_pat env p@(ConPatOut { pat_arg_tys = tys - , pat_tvs = tyvars - , pat_dicts = evs - , pat_binds = binds - , pat_args = args - , pat_wrap = wrapper - , pat_con = L _ con }) +zonk_pat env p@(ConPat { pat_con = L _ con + , pat_args = args + , pat_con_ext = p'@(ConPatTc + { cpt_tvs = tyvars + , cpt_dicts = evs + , cpt_binds = binds + , cpt_wrap = wrapper + , cpt_arg_tys = tys + }) + }) = ASSERT( all isImmutableTyVar tyvars ) do { new_tys <- mapM (zonkTcTypeToTypeX env) tys @@ -1384,12 +1389,19 @@ zonk_pat env p@(ConPatOut { pat_arg_tys = tys ; (env2, new_binds) <- zonkTcEvBinds env1 binds ; (env3, new_wrapper) <- zonkCoFn env2 wrapper ; (env', new_args) <- zonkConStuff env3 args - ; return (env', p { pat_arg_tys = new_tys, - pat_tvs = new_tyvars, - pat_dicts = new_evs, - pat_binds = new_binds, - pat_args = new_args, - pat_wrap = new_wrapper}) } + ; pure ( env' + , p + { pat_args = new_args + , pat_con_ext = p' + { cpt_arg_tys = new_tys + , cpt_tvs = new_tyvars + , cpt_dicts = new_evs + , cpt_binds = new_binds + , cpt_wrap = new_wrapper + } + } + ) + } where doc = text "In the type of an element of an unboxed tuple pattern:" $$ ppr p @@ -1420,19 +1432,20 @@ zonk_pat env (NPlusKPat ty (L loc n) (L l lit1) lit2 e1 e2) ; return (extendIdZonkEnv env2 n', NPlusKPat ty' (L loc n') (L l lit1') lit2' e1' e2') } -zonk_pat env (CoPat x co_fn pat ty) +zonk_pat env (XPat (CoPat co_fn pat ty)) = do { (env', co_fn') <- zonkCoFn env co_fn ; (env'', pat') <- zonkPat env' (noLoc pat) ; ty' <- zonkTcTypeToTypeX env'' ty - ; return (env'', CoPat x co_fn' (unLoc pat') ty') } + ; return (env'', XPat $ CoPat co_fn' (unLoc pat') ty') + } zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat) --------------------------- zonkConStuff :: ZonkEnv - -> HsConDetails (OutPat GhcTcId) (HsRecFields id (OutPat GhcTcId)) + -> HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc)) -> TcM (ZonkEnv, - HsConDetails (OutPat GhcTc) (HsRecFields id (OutPat GhcTc))) + HsConDetails (LPat GhcTc) (HsRecFields id (LPat GhcTc))) zonkConStuff env (PrefixCon pats) = do { (env', pats') <- zonkPats env pats ; return (env', PrefixCon pats') } @@ -1451,7 +1464,7 @@ zonkConStuff env (RecCon (HsRecFields rpats dd)) -- Field selectors have declared types; hence no zonking --------------------------- -zonkPats :: ZonkEnv -> [OutPat GhcTcId] -> TcM (ZonkEnv, [OutPat GhcTc]) +zonkPats :: ZonkEnv -> [LPat GhcTc] -> TcM (ZonkEnv, [LPat GhcTc]) zonkPats env [] = return (env, []) zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat ; (env', pats') <- zonkPats env1 pats ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -2155,8 +2155,8 @@ checkFamPatBinders fam_tc qtvs pats rhs , ppr (mkTyConApp fam_tc pats) , text "qtvs:" <+> ppr qtvs , text "rhs_tvs:" <+> ppr (fvVarSet rhs_fvs) - , text "pat_tvs:" <+> ppr pat_tvs - , text "inj_pat_tvs:" <+> ppr inj_pat_tvs ] + , text "cpt_tvs:" <+> ppr cpt_tvs + , text "inj_cpt_tvs:" <+> ppr inj_cpt_tvs ] -- Check for implicitly-bound tyvars, mentioned on the -- RHS but not bound on the LHS @@ -2176,23 +2176,23 @@ checkFamPatBinders fam_tc qtvs pats rhs (text "used in") } where - pat_tvs = tyCoVarsOfTypes pats - inj_pat_tvs = fvVarSet $ injectiveVarsOfTypes False pats + cpt_tvs = tyCoVarsOfTypes pats + inj_cpt_tvs = fvVarSet $ injectiveVarsOfTypes False pats -- The type variables that are in injective positions. -- See Note [Dodgy binding sites in type family instances] -- NB: The False above is irrelevant, as we never have type families in -- patterns. -- -- NB: It's OK to use the nondeterministic `fvVarSet` function here, - -- since the order of `inj_pat_tvs` is never revealed in an error + -- since the order of `inj_cpt_tvs` is never revealed in an error -- message. rhs_fvs = tyCoFVsOfType rhs - used_tvs = pat_tvs `unionVarSet` fvVarSet rhs_fvs + used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs -- Bound but not used at all - bad_rhs_tvs = filterOut (`elemVarSet` inj_pat_tvs) (fvVarList rhs_fvs) + bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) -- Used on RHS but not bound on LHS - dodgy_tvs = pat_tvs `minusVarSet` inj_pat_tvs + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs tvs what what2 = unless (null tvs) $ addErrAt (getSrcSpan (head tvs)) $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1268,12 +1268,22 @@ cvtp (UnboxedSumP p alt arity) ; return $ SumPat noExtField p' alt arity } cvtp (ConP s ps) = do { s' <- cNameL s; ps' <- cvtPats ps ; let pps = map (parenthesizePat appPrec) ps' - ; return $ ConPatIn s' (PrefixCon pps) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = s' + , pat_args = PrefixCon pps + } + } cvtp (InfixP p1 s p2) = do { s' <- cNameL s; p1' <- cvtPat p1; p2' <- cvtPat p2 ; wrapParL (ParPat noExtField) $ - ConPatIn s' $ - InfixCon (parenthesizePat opPrec p1') - (parenthesizePat opPrec p2') } + ConPat + { pat_con_ext = NoExtField + , pat_con = s' + , pat_args = InfixCon + (parenthesizePat opPrec p1') + (parenthesizePat opPrec p2') + } + } -- See Note [Operator association] cvtp (UInfixP p1 s p2) = do { p1' <- cvtPat p1; cvtOpAppP p1' s p2 } -- Note [Converting UInfix] cvtp (ParensP p) = do { p' <- cvtPat p; @@ -1286,8 +1296,12 @@ cvtp (TH.AsP s p) = do { s' <- vNameL s; p' <- cvtPat p ; return $ AsPat noExtField s' p' } cvtp TH.WildP = return $ WildPat noExtField cvtp (RecP c fs) = do { c' <- cNameL c; fs' <- mapM cvtPatFld fs - ; return $ ConPatIn c' - $ Hs.RecCon (HsRecFields fs' Nothing) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = c' + , pat_args = Hs.RecCon $ HsRecFields fs' Nothing + } + } cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} @@ -1317,7 +1331,12 @@ cvtOpAppP x op1 (UInfixP y op2 z) cvtOpAppP x op y = do { op' <- cNameL op ; y' <- cvtPat y - ; return (ConPatIn op' (InfixCon x y')) } + ; return $ ConPat + { pat_con_ext = noExtField + , pat_con = op' + , pat_args = InfixCon x y' + } + } ----------------------------------------------------------- -- Types and type variables ===================================== testsuite/tests/ghc-api/T6145.hs ===================================== @@ -39,7 +39,7 @@ main = do = not (isEmptyBag (filterBag isDataCon bs)) isDataCon (L l (f at FunBind {})) | (MG _ (L _ (m:_)) _) <- fun_matches f, - ((L _ (c at ConPatOut{})):_)<-hsLMatchPats m, + ((L _ (c at ConPat{})):_)<-hsLMatchPats m, (L l _)<-pat_con c = isGoodSrcSpan l -- Check that the source location is a good one isDataCon _ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 20bf93490b37c0410d85a0ad4d38f9ddc2253589 +Subproject commit da4e2bd788b6231494d6ac56a8e88bcfa4be51f6 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c42754d5fdd3c2db554d9541bab22d1b3def4be7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c42754d5fdd3c2db554d9541bab22d1b3def4be7 You're receiving 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 23 22:33:32 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 23 Apr 2020 18:33:32 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Add :doc to GHC.Prim Message-ID: <5ea217bc4f9f0_61673f81e706321068048cb@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - 10 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/ghc.mk - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Builders/GenPrimopCode.hs - testsuite/tests/ghci/scripts/all.T - + testsuite/tests/ghci/scripts/ghci066.script - + testsuite/tests/ghci/scripts/ghci066.stdout - utils/genprimopcode/Main.hs Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -16,7 +16,7 @@ module GHC.Builtin.PrimOps ( primOpOutOfLine, primOpCodeSize, primOpOkForSpeculation, primOpOkForSideEffects, - primOpIsCheap, primOpFixity, + primOpIsCheap, primOpFixity, primOpDocs, getPrimOpResultInfo, isComparisonPrimOp, PrimOpResultInfo(..), @@ -161,6 +161,19 @@ primOpStrictness :: PrimOp -> Arity -> StrictSig primOpFixity :: PrimOp -> Maybe Fixity #include "primop-fixity.hs-incl" +{- +************************************************************************ +* * +\subsubsection{Docs} +* * +************************************************************************ + +See Note [GHC.Prim Docs] +-} + +primOpDocs :: [(String, String)] +#include "primop-docs.hs-incl" + {- ************************************************************************ * * ===================================== compiler/GHC/Builtin/Utils.hs ===================================== @@ -34,6 +34,7 @@ module GHC.Builtin.Utils ( primOpRules, builtinRules, ghcPrimExports, + ghcPrimDeclDocs, primOpId, -- * Random other things @@ -71,11 +72,13 @@ import GHC.Core.TyCon import GHC.Types.Unique.FM import Util import GHC.Builtin.Types.Literals ( typeNatTyCons ) +import GHC.Hs.Doc import Control.Applicative ((<|>)) -import Data.List ( intercalate ) +import Data.List ( intercalate , find ) import Data.Array import Data.Maybe +import qualified Data.Map as Map {- ************************************************************************ @@ -256,6 +259,17 @@ ghcPrimExports [ AvailTC n [n] [] | tc <- funTyCon : exposedPrimTyCons, let n = tyConName tc ] +ghcPrimDeclDocs :: DeclDocMap +ghcPrimDeclDocs = DeclDocMap $ Map.fromList $ mapMaybe findName primOpDocs + where + names = map idName ghcPrimIds ++ + map (idName . primOpId) allThePrimOps ++ + map tyConName (funTyCon : exposedPrimTyCons) + findName (nameStr, doc) + | Just name <- find ((nameStr ==) . getOccString) names + = Just (name, mkHsDocString doc) + | otherwise = Nothing + {- ************************************************************************ * * ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -1049,7 +1049,8 @@ ghcPrimIface mi_exports = ghcPrimExports, mi_decls = [], mi_fixities = fixities, - mi_final_exts = (mi_final_exts empty_iface){ mi_fix_fn = mkIfaceFixCache fixities } + mi_final_exts = (mi_final_exts empty_iface){ mi_fix_fn = mkIfaceFixCache fixities }, + mi_decl_docs = ghcPrimDeclDocs -- See Note [GHC.Prim Docs] } where empty_iface = emptyFullModIface gHC_PRIM ===================================== compiler/ghc.mk ===================================== @@ -119,7 +119,8 @@ PRIMOP_BITS_NAMES = primop-data-decl.hs-incl \ primop-vector-uniques.hs-incl \ primop-vector-tys.hs-incl \ primop-vector-tys-exports.hs-incl \ - primop-vector-tycons.hs-incl + primop-vector-tycons.hs-incl \ + primop-docs.hs-incl PRIMOP_BITS_STAGE1 = $(addprefix compiler/stage1/build/,$(PRIMOP_BITS_NAMES)) PRIMOP_BITS_STAGE2 = $(addprefix compiler/stage2/build/,$(PRIMOP_BITS_NAMES)) @@ -166,6 +167,8 @@ compiler/stage$1/build/primop-vector-tys-exports.hs-incl: compiler/stage$1/build "$$(genprimopcode_INPLACE)" --primop-vector-tys-exports < $$< > $$@ compiler/stage$1/build/primop-vector-tycons.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --primop-vector-tycons < $$< > $$@ +compiler/stage$1/build/primop-docs.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) + "$$(genprimopcode_INPLACE)" --wired-in-docs < $$< > $$@ # Usages aren't used any more; but the generator # can still generate them if we want them back ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -73,7 +73,8 @@ compilerDependencies = do , "primop-vector-tycons.hs-incl" , "primop-vector-tys-exports.hs-incl" , "primop-vector-tys.hs-incl" - , "primop-vector-uniques.hs-incl" ] ] + , "primop-vector-uniques.hs-incl" + , "primop-docs.hs-incl" ] ] generatedDependencies :: Expr [FilePath] generatedDependencies = do ===================================== hadrian/src/Settings/Builders/GenPrimopCode.hs ===================================== @@ -21,4 +21,5 @@ genPrimopCodeBuilderArgs = builder GenPrimopCode ? mconcat , output "//primop-vector-tys.hs-incl" ? arg "--primop-vector-tys" , output "//primop-vector-tys-exports.hs-incl" ? arg "--primop-vector-tys-exports" , output "//primop-vector-tycons.hs-incl" ? arg "--primop-vector-tycons" + , output "//primop-docs.hs-incl" ? arg "--wired-in-docs" , output "//primop-usage.hs-incl" ? arg "--usage" ] ===================================== testsuite/tests/ghci/scripts/all.T ===================================== @@ -105,6 +105,7 @@ test('ghci062', [extra_files(['ghci062/', 'ghci062/Test.hs']), test('ghci063', normal, ghci_script, ['ghci063.script']) test('ghci064', normal, ghci_script, ['ghci064.script']) test('ghci065', [extra_hc_opts("-haddock")], ghci_script, ['ghci065.script']) +test('ghci066', normal, ghci_script, ['ghci066.script']) test('T2452', [extra_hc_opts("-fno-implicit-import-qualified")], ghci_script, ['T2452.script']) test('T2766', normal, ghci_script, ['T2766.script']) ===================================== testsuite/tests/ghci/scripts/ghci066.script ===================================== @@ -0,0 +1,2 @@ +:set -XMagicHash +:doc GHC.Prim.byteSwap# ===================================== testsuite/tests/ghci/scripts/ghci066.stdout ===================================== @@ -0,0 +1 @@ +Swap bytes in a word. ===================================== utils/genprimopcode/Main.hs ===================================== @@ -189,6 +189,9 @@ main = getArgs >>= \args -> "--make-latex-doc" -> putStr (gen_latex_doc p_o_specs) + "--wired-in-docs" + -> putStr (gen_wired_in_docs p_o_specs) + _ -> error "Should not happen, known_args out of sync?" ) @@ -211,7 +214,8 @@ known_args "--primop-vector-tycons", "--make-haskell-wrappers", "--make-haskell-source", - "--make-latex-doc" + "--make-latex-doc", + "--wired-in-docs" ] ------------------------------------------------------------------ @@ -360,28 +364,31 @@ gen_hs_source (Info defaults entries) = prim_data t = [ "data " ++ pprTy t ] - unlatex s = case s of - '\\':'t':'e':'x':'t':'t':'t':'{':cs -> markup "@" "@" cs - '{':'\\':'t':'e':'x':'t':'t':'t':' ':cs -> markup "@" "@" cs - '{':'\\':'t':'t':cs -> markup "@" "@" cs - '{':'\\':'i':'t':cs -> markup "/" "/" cs - '{':'\\':'e':'m':cs -> markup "/" "/" cs - c : cs -> c : unlatex cs - "" -> "" - markup s t xs = s ++ mk (dropWhile isSpace xs) - where mk "" = t - mk ('\n':cs) = ' ' : mk cs - mk ('}':cs) = t ++ unlatex cs - mk (c:cs) = c : mk cs escape = concatMap (\c -> if c `elem` special then '\\':c:[] else c:[]) where special = "/'`\"@<" +unlatex :: String -> String +unlatex s = case s of + '\\':'t':'e':'x':'t':'t':'t':'{':cs -> markup "@" "@" cs + '{':'\\':'t':'e':'x':'t':'t':'t':' ':cs -> markup "@" "@" cs + '{':'\\':'t':'t':cs -> markup "@" "@" cs + '{':'\\':'i':'t':cs -> markup "/" "/" cs + '{':'\\':'e':'m':cs -> markup "/" "/" cs + c : cs -> c : unlatex cs + "" -> "" + where markup b e xs = b ++ mk (dropWhile isSpace xs) + where mk "" = e + mk ('\n':cs) = ' ' : mk cs + mk ('}':cs) = e ++ unlatex cs + mk (c:cs) = c : mk cs + -- | Extract a string representation of the name getName :: Entry -> Maybe String getName PrimOpSpec{ name = n } = Just n getName PrimVecOpSpec{ name = n } = Just n getName PseudoOpSpec{ name = n } = Just n getName PrimTypeSpec{ ty = TyApp tc _ } = Just (show tc) +getName PrimVecTypeSpec{ ty = TyApp tc _ } = Just (show tc) getName _ = Nothing {- Note [Placeholder declarations] @@ -782,6 +789,30 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries) -> unlines alternatives ++ fn_name ++ " _ = " ++ getAltRhs xx ++ "\n" +{- +Note [GHC.Prim Docs] +~~~~~~~~~~~~~~~~~~~~ +For haddocks of GHC.Prim we generate a dummy haskell file (gen_hs_source) that +contains the type signatures and the commends (but no implementations) +specifically for consumption by haddock. + +GHCi's :doc command reads directly from ModIface's though, and GHC.Prim has a +wired-in iface that has nothing to do with the above haskell file. The code +below converts primops.txt into an intermediate form that would later be turned +into a proper DeclDocMap. + +We output the docs as a list of pairs (name, docs). We use stringy names here +because mapping names to "Name"s is difficult for things like primtypes and +pseudoops. +-} +gen_wired_in_docs :: Info -> String +gen_wired_in_docs (Info _ entries) + = "primOpDocs =\n [ " ++ intercalate "\n , " (catMaybes $ map mkDoc $ concatMap desugarVectorSpec entries) ++ "\n ]\n" + where + mkDoc po | Just poName <- getName po + , not $ null $ desc po = Just $ show (poName, unlatex $ desc po) + | otherwise = Nothing + ------------------------------------------------------------------ -- Create PrimOpInfo text from PrimOpSpecs ----------------------- ------------------------------------------------------------------ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c42754d5fdd3c2db554d9541bab22d1b3def4be7...0ac29c885fba7ed69de83a597cdbd03696c9ed13 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c42754d5fdd3c2db554d9541bab22d1b3def4be7...0ac29c885fba7ed69de83a597cdbd03696c9ed13 You're receiving 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 23 22:51:25 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 23 Apr 2020 18:51:25 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ea21bed1c012_61673f81cc6e89e868083a7@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: efd9ac53 by Simon Peyton Jones at 2020-04-23T23:51:07+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. The ticket is https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * isTauTy: was replying True for (Show a => a ->a), which is utterly bogus. Fixed. * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: fail faster. we want to fail fast in T11142 Another example: T15629 And keep all equalities in dropMisleading. This gives better reporting in T12593 for example. * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 26 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/efd9ac5328bf77ea44cd56b094c7f0f5bfe4c886 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/efd9ac5328bf77ea44cd56b094c7f0f5bfe4c886 You're receiving 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 24 01:43:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 23 Apr 2020 21:43:47 -0400 Subject: [Git][ghc/ghc][wip/runRW] 5 commits: CoreLint: Again accept casts Message-ID: <5ea244533791f_61673f81ee93dc1c6830417@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 7d1b4767 by Ben Gamari at 2020-04-21T21:27:03+00:00 CoreLint: Again accept casts - - - - - 179d0bbe by Simon Peyton Jones at 2020-04-21T23:17:48+00:00 Make Lint check return type of a join point Consider join x = rhs in body It's important that the type of 'rhs' is the same as the type of 'body', but Lint wasn't checking that invariant. Now it does! This was exposed by investigation into !3113. - - - - - 54fc0e73 by Simon Peyton Jones at 2020-04-21T23:17:49+00:00 Do not float join points in exprIsConApp_maybe We hvae been making exprIsConApp_maybe cleverer in recent times: commit b78cc64e923716ac0512c299f42d4d0012306c05 Date: Thu Nov 15 17:14:31 2018 +0100 Make constructor wrappers inline only during the final phase commit 7833cf407d1f608bebb1d38bb99d3035d8d735e6 Date: Thu Jan 24 17:58:50 2019 +0100 Look through newtype wrappers (Trac #16254) commit c25b135ff5b9c69a90df0ccf51b04952c2dc6ee1 Date: Thu Feb 21 12:03:22 2019 +0000 Fix exprIsConApp_maybe But alas there was still a bug, now immortalised in Note [Don't float join points] in SimpleOpt. It's quite hard to trigger because it requires a dead join point, but it came up when compiling Cabal Cabal.Distribution.Fields.Lexer.hs, when working on !3113. Happily, the fix is extremly easy. Finding the bug was not so easy. - - - - - be9bb0d7 by Ben Gamari at 2020-04-23T13:48:34+00:00 Merge commit 'fad536ea7e2622fb1102df55bd642b4153603503' into HEAD - - - - - 6965215a by Ben Gamari at 2020-04-24T00:46:31+00:00 CoreLint: Accept oversaturated applications of runRW# - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -780,10 +780,9 @@ type LintedId = Id -- | Lint an expression cast through the given coercion, returning the type -- resulting from the cast. -lintCastExpr :: CoreExpr -> Coercion -> LintM LintedType -lintCastExpr expr co - = do { expr_ty <- markAllJoinsBad $ lintCoreExpr expr - ; co' <- lintCoercion co +lintCastExpr :: CoreExpr -> LintedType -> Coercion -> LintM LintedType +lintCastExpr expr expr_ty co + = do { co' <- lintCoercion co ; let (Pair from_ty to_ty, role) = coercionKindRole co' ; checkValueType to_ty $ text "target of cast" <+> quotes (ppr co') @@ -808,7 +807,8 @@ lintCoreExpr (Lit lit) = return (literalType lit) lintCoreExpr (Cast expr co) - = markAllJoinsBad $ lintCastExpr expr co + = do expr_ty <- markAllJoinsBad $ lintCoreExpr expr + lintCastExpr expr expr_ty co lintCoreExpr (Tick tickish expr) = do case tickish of @@ -870,11 +870,22 @@ lintCoreExpr e@(Let (Rec pairs) body) lintCoreExpr e@(App _ _) | Var fun <- fun , fun `hasKey` runRWKey - , [arg_ty1, arg_ty2, arg3] <- args + -- N.B. we may have an over-saturated application of the form: + -- runRW (\s -> \x -> ...) y + , arg_ty1 : arg_ty2 : arg3 : rest <- args = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 - ; arg3_ty <- lintJoinLams 1 (Just fun) arg3 - ; lintValApp arg3 fun_ty2 arg3_ty } + -- The simplifier pushes casts out of the continuation lambda; + -- consequently we need to handle the case that the continuation is a + -- cast lambda. See Note [Casts and lambdas] in + -- GHC.Core.Opt.Simplify.Utils. + ; arg3_ty <- case arg3 of + Cast expr co -> do + expr_ty <- lintJoinLams 1 (Just fun) expr + lintCastExpr expr expr_ty co + _ -> lintJoinLams 1 (Just fun) arg3 + ; app_ty <- lintValApp arg3 fun_ty2 arg3_ty + ; lintCoreArgs app_ty rest } | Var fun <- fun , fun `hasKey` runRWKey View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fad536ea7e2622fb1102df55bd642b4153603503...6965215a5b3b4982af4321a2714d11756a688325 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fad536ea7e2622fb1102df55bd642b4153603503...6965215a5b3b4982af4321a2714d11756a688325 You're receiving 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 24 02:48:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 23 Apr 2020 22:48:36 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/nonmoving-census Message-ID: <5ea25384b9c5c_61673f81e7063210683411e@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/nonmoving-census at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/nonmoving-census You're receiving 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 24 02:48:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 23 Apr 2020 22:48:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/no-gc-spinlock Message-ID: <5ea253916eae5_61673f81afeb5fbc6834346@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/no-gc-spinlock at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/no-gc-spinlock You're receiving 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 24 03:34:21 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 23 Apr 2020 23:34:21 -0400 Subject: [Git][ghc/ghc][wip/nonmoving-census] 3 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5ea25e3df8ba_616776d1c7468359d6@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/nonmoving-census at Glasgow Haskell Compiler / GHC Commits: dd790438 by Ben Gamari at 2020-04-23T22:54:21-04:00 rts: Enable tracing of nonmoving heap census with -ln - - - - - 37913521 by Ben Gamari at 2020-04-23T23:33:54-04:00 users guide: Move eventlog documentation users guide - - - - - d0eec158 by Ben Gamari at 2020-04-23T23:34:00-04:00 users guide: Add documentation for non-moving GC events - - - - - 6 changed files: - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - rts/RtsFlags.c - rts/sm/NonMoving.c Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -283,8 +283,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -9,6 +9,479 @@ user-defined tracing events. This section is intended for implementors of tooling which consume these events. +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). + + .. _heap-profiler-events: Heap profiler event log output @@ -28,11 +501,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +517,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +552,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +565,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +582,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +612,138 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ + +A variable-length packet encoding a profile sample. + +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1161,6 +1161,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== rts/RtsFlags.c ===================================== @@ -382,6 +382,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -1125,6 +1125,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a921ac9df649172b54c479729bae6942c0bdd071...d0eec158075cfc640c9b46160f0e9f8c9cb7c309 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a921ac9df649172b54c479729bae6942c0bdd071...d0eec158075cfc640c9b46160f0e9f8c9cb7c309 You're receiving 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 24 03:50:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 23 Apr 2020 23:50:22 -0400 Subject: [Git][ghc/ghc][wip/nonmoving-census] 3 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5ea261febb123_61673f81cc6e89e86837533@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/nonmoving-census at Glasgow Haskell Compiler / GHC Commits: 77d3b909 by Ben Gamari at 2020-04-23T23:46:56-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - af13d8a2 by Ben Gamari at 2020-04-23T23:50:15-04:00 users guide: Move eventlog documentation users guide - - - - - 3997b162 by Ben Gamari at 2020-04-23T23:50:15-04:00 users guide: Add documentation for non-moving GC events - - - - - 6 changed files: - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - rts/RtsFlags.c - rts/sm/NonMoving.c Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -283,8 +283,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -1,3 +1,5 @@ +.. _eventlog-encodings: + Eventlog encodings ================== @@ -7,6 +9,481 @@ thread scheduling events, garbage collection statistics, profiling information, user-defined tracing events. This section is intended for implementors of tooling which consume these events. +GHC ships with a C header file (``EventlogFormat.h``) which provides symbolic +names for the event type IDs described in this file. + + +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). .. _heap-profiler-events: @@ -28,11 +505,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +521,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +556,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +569,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +586,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +616,142 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- + +A variable-length packet encoding a profile sample. + +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. These are enabled +with the ``+RTS -lg`` event-set. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +The non-moving heap census events (enabled with the ``+RTS -ln`` event-set) are +intended to provide insight into fragmentation of the non-moving heap. + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1161,6 +1161,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. @@ -1186,9 +1190,8 @@ When the program is linked with the :ghc-flag:`-eventlog` option accurate mode every spark event is logged individually. The latter has a higher runtime overhead and is not enabled by default. - The format of the log file is described by the header - ``EventLogFormat.h`` that comes with GHC, and it can be parsed in - Haskell using the + The format of the log file is described in this users guide in + :ref:`eventlog-encodings` It can be parsed in Haskell using the `ghc-events `__ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== rts/RtsFlags.c ===================================== @@ -382,6 +382,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -1125,6 +1125,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0eec158075cfc640c9b46160f0e9f8c9cb7c309...3997b162f2a4ce5efd54d60c571168c63b329511 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0eec158075cfc640c9b46160f0e9f8c9cb7c309...3997b162f2a4ce5efd54d60c571168c63b329511 You're receiving 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 24 09:34:24 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 24 Apr 2020 05:34:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18092 Message-ID: <5ea2b2a0e1379_6167e5c4f1468427f9@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/T18092 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18092 You're receiving 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 24 09:40:20 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 24 Apr 2020 05:40:20 -0400 Subject: [Git][ghc/ghc][wip/T18092] Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Message-ID: <5ea2b40482325_616776d1c74684435c@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18092 at Glasgow Haskell Compiler / GHC Commits: 2ae68627 by Sebastian Graf at 2020-04-24T11:39:27+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. As a result, `decodeDoubleInteger` no longer needs to be known-key. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - 3 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - libraries/integer-gmp/src/GHC/Integer/Type.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -381,7 +381,6 @@ basicKnownKeyNames quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName, @@ -1125,7 +1124,6 @@ integerTyConName, mkIntegerName, integerSDataConName, quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName :: Name @@ -1163,7 +1161,6 @@ floatFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "floatFromInteger") doubleFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "doubleFromInteger") doubleFromIntegerIdKey encodeFloatIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeFloatInteger") encodeFloatIntegerIdKey encodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeDoubleInteger") encodeDoubleIntegerIdKey -decodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "decodeDoubleInteger") decodeDoubleIntegerIdKey gcdIntegerName = varQual gHC_INTEGER_TYPE (fsLit "gcdInteger") gcdIntegerIdKey lcmIntegerName = varQual gHC_INTEGER_TYPE (fsLit "lcmInteger") lcmIntegerIdKey andIntegerName = varQual gHC_INTEGER_TYPE (fsLit "andInteger") andIntegerIdKey @@ -2149,7 +2146,6 @@ mkIntegerIdKey, smallIntegerIdKey, wordToIntegerIdKey, quotIntegerIdKey, remIntegerIdKey, divIntegerIdKey, modIntegerIdKey, floatFromIntegerIdKey, doubleFromIntegerIdKey, encodeFloatIntegerIdKey, encodeDoubleIntegerIdKey, - decodeDoubleIntegerIdKey, gcdIntegerIdKey, lcmIntegerIdKey, andIntegerIdKey, orIntegerIdKey, xorIntegerIdKey, complementIntegerIdKey, shiftLIntegerIdKey, shiftRIntegerIdKey :: Unique @@ -2193,7 +2189,8 @@ shiftRIntegerIdKey = mkPreludeMiscIdUnique 96 wordToIntegerIdKey = mkPreludeMiscIdUnique 97 word64ToIntegerIdKey = mkPreludeMiscIdUnique 98 int64ToIntegerIdKey = mkPreludeMiscIdUnique 99 -decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 +-- This one is "free" +-- decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -13,8 +13,7 @@ ToDo: -} {-# LANGUAGE CPP, RankNTypes, PatternSynonyms, ViewPatterns, RecordWildCards, - DeriveFunctor #-} -{-# LANGUAGE LambdaCase #-} + DeriveFunctor, LambdaCase, TypeApplications #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.ConstantFold @@ -249,18 +248,19 @@ primOpRules nm = \case , inversePrimOp FloatNegOp ] -- Double - DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) - , identity zerod ] - DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) - , rightIdentity zerod ] - DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) - , identity oned - , strengthReduction twod DoubleAddOp ] + DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) + , identity zerod ] + DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) + , rightIdentity zerod ] + DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) + , identity oned + , strengthReduction twod DoubleAddOp ] -- zeroElem zerod doesn't hold because of NaN - DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) - , rightIdentity oned ] - DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp - , inversePrimOp DoubleNegOp ] + DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) + , rightIdentity oned ] + DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp + , inversePrimOp DoubleNegOp ] + DoubleDecode_Int64Op -> mkPrimOpRule nm 1 [ unaryLit doubleDecodeOp ] -- Relational operators @@ -510,6 +510,23 @@ doubleOp2 op env (LitDouble f1) (LitDouble f2) = Just (mkDoubleVal env (f1 `op` f2)) doubleOp2 _ _ _ _ = Nothing +-------------------------- +doubleDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr +doubleDecodeOp env (LitDouble ((decodeFloat . fromRational @Double) -> (m, e))) + = Just $ mkCoreUbxTup [iNT64Ty, intPrimTy] + [ Lit (mkLitINT64 (roPlatform env) (toInteger m)) + , mkIntVal (roPlatform env) (toInteger e) ] + where +#if WORD_SIZE_IN_BITS < 64 + iNT64Ty = intPrimTy + mkLitINT64 = mkLitInt64Wrap +#else + iNT64Ty = int64PrimTy + mkLitINT64 = mkLitIntWrap +#endif +doubleDecodeOp _ _ + = Nothing + -------------------------- {- Note [The litEq rule: converting equality to case] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1317,7 +1334,6 @@ builtinIntegerRules = rule_encodeFloat "encodeFloatInteger" encodeFloatIntegerName mkFloatLitFloat, rule_convert "floatFromInteger" floatFromIntegerName (\_ -> mkFloatLitFloat), rule_encodeFloat "encodeDoubleInteger" encodeDoubleIntegerName mkDoubleLitDouble, - rule_decodeDouble "decodeDoubleInteger" decodeDoubleIntegerName, rule_convert "doubleFromInteger" doubleFromIntegerName (\_ -> mkDoubleLitDouble), rule_rationalTo "rationalToFloat" rationalToFloatName mkFloatExpr, rule_rationalTo "rationalToDouble" rationalToDoubleName mkDoubleExpr, @@ -1390,9 +1406,6 @@ builtinIntegerRules = rule_encodeFloat str name op = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 2, ru_try = match_Integer_Int_encodeFloat op } - rule_decodeDouble str name - = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, - ru_try = match_decodeDouble } rule_XToIntegerToX str name toIntegerName = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, ru_try = match_XToIntegerToX toIntegerName } @@ -1747,22 +1760,6 @@ match_rationalTo mkLit _ id_unf _ [xl, yl] = Just (mkLit (fromRational (x % y))) match_rationalTo _ _ _ _ _ = Nothing -match_decodeDouble :: RuleFun -match_decodeDouble env id_unf fn [xl] - | Just (LitDouble x) <- exprIsLiteral_maybe id_unf xl - = case splitFunTy_maybe (idType fn) of - Just (_, res) - | Just [_lev1, _lev2, integerTy, intHashTy] <- tyConAppArgs_maybe res - -> case decodeFloat (fromRational x :: Double) of - (y, z) -> - Just $ mkCoreUbxTup [integerTy, intHashTy] - [Lit (mkLitInteger y integerTy), - Lit (mkLitInt (roPlatform env) (toInteger z))] - _ -> - pprPanic "match_decodeDouble: Id has the wrong type" - (ppr fn <+> dcolon <+> ppr (idType fn)) -match_decodeDouble _ _ _ _ = Nothing - match_XToIntegerToX :: Name -> RuleFun match_XToIntegerToX n _ _ _ [App (Var x) y] | idName x == n ===================================== libraries/integer-gmp/src/GHC/Integer/Type.hs ===================================== @@ -1618,7 +1618,6 @@ foreign import ccall unsafe "integer_gmp_invert" -- Conversions to/from floating point decodeDoubleInteger :: Double# -> (# Integer, Int# #) --- decodeDoubleInteger 0.0## = (# S# 0#, 0# #) #if WORD_SIZE_IN_BITS == 64 decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# S# m#, e# #) @@ -1626,7 +1625,7 @@ decodeDoubleInteger x = case decodeDouble_Int64# x of decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# int64ToInteger m#, e# #) #endif -{-# CONSTANT_FOLDED decodeDoubleInteger #-} +{-# INLINE decodeDoubleInteger #-} -- provided by GHC's RTS foreign import ccall unsafe "__int_encodeDouble" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ae68627e79e532cc1e75f1c26d5e6fbe7f4ac08 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ae68627e79e532cc1e75f1c26d5e6fbe7f4ac08 You're receiving 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 24 10:00:36 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 24 Apr 2020 06:00:36 -0400 Subject: [Git][ghc/ghc][wip/T18092] Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Message-ID: <5ea2b8c49fab5_61673f81ef22dee46850980@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18092 at Glasgow Haskell Compiler / GHC Commits: a3c86479 by Sebastian Graf at 2020-04-24T12:00:19+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. As a result, `decodeDoubleInteger` no longer needs to be known-key. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - 3 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - libraries/integer-gmp/src/GHC/Integer/Type.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -381,7 +381,6 @@ basicKnownKeyNames quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName, @@ -1125,7 +1124,6 @@ integerTyConName, mkIntegerName, integerSDataConName, quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName :: Name @@ -1163,7 +1161,6 @@ floatFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "floatFromInteger") doubleFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "doubleFromInteger") doubleFromIntegerIdKey encodeFloatIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeFloatInteger") encodeFloatIntegerIdKey encodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeDoubleInteger") encodeDoubleIntegerIdKey -decodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "decodeDoubleInteger") decodeDoubleIntegerIdKey gcdIntegerName = varQual gHC_INTEGER_TYPE (fsLit "gcdInteger") gcdIntegerIdKey lcmIntegerName = varQual gHC_INTEGER_TYPE (fsLit "lcmInteger") lcmIntegerIdKey andIntegerName = varQual gHC_INTEGER_TYPE (fsLit "andInteger") andIntegerIdKey @@ -2149,7 +2146,6 @@ mkIntegerIdKey, smallIntegerIdKey, wordToIntegerIdKey, quotIntegerIdKey, remIntegerIdKey, divIntegerIdKey, modIntegerIdKey, floatFromIntegerIdKey, doubleFromIntegerIdKey, encodeFloatIntegerIdKey, encodeDoubleIntegerIdKey, - decodeDoubleIntegerIdKey, gcdIntegerIdKey, lcmIntegerIdKey, andIntegerIdKey, orIntegerIdKey, xorIntegerIdKey, complementIntegerIdKey, shiftLIntegerIdKey, shiftRIntegerIdKey :: Unique @@ -2193,7 +2189,8 @@ shiftRIntegerIdKey = mkPreludeMiscIdUnique 96 wordToIntegerIdKey = mkPreludeMiscIdUnique 97 word64ToIntegerIdKey = mkPreludeMiscIdUnique 98 int64ToIntegerIdKey = mkPreludeMiscIdUnique 99 -decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 +-- This one is "free" +-- decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -13,8 +13,7 @@ ToDo: -} {-# LANGUAGE CPP, RankNTypes, PatternSynonyms, ViewPatterns, RecordWildCards, - DeriveFunctor #-} -{-# LANGUAGE LambdaCase #-} + DeriveFunctor, LambdaCase, TypeApplications #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.ConstantFold @@ -249,18 +248,19 @@ primOpRules nm = \case , inversePrimOp FloatNegOp ] -- Double - DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) - , identity zerod ] - DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) - , rightIdentity zerod ] - DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) - , identity oned - , strengthReduction twod DoubleAddOp ] + DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) + , identity zerod ] + DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) + , rightIdentity zerod ] + DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) + , identity oned + , strengthReduction twod DoubleAddOp ] -- zeroElem zerod doesn't hold because of NaN - DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) - , rightIdentity oned ] - DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp - , inversePrimOp DoubleNegOp ] + DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) + , rightIdentity oned ] + DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp + , inversePrimOp DoubleNegOp ] + DoubleDecode_Int64Op -> mkPrimOpRule nm 1 [ unaryLit doubleDecodeOp ] -- Relational operators @@ -510,6 +510,22 @@ doubleOp2 op env (LitDouble f1) (LitDouble f2) = Just (mkDoubleVal env (f1 `op` f2)) doubleOp2 _ _ _ _ = Nothing +-------------------------- +doubleDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr +doubleDecodeOp env (LitDouble ((decodeFloat . fromRational @Double) -> (m, e))) + = Just $ mkCoreUbxTup [iNT64Ty, intPrimTy] + [ Lit (mkLitINT64 (roPlatform env) (toInteger m)) + , mkIntVal platform (toInteger e) ] + where + platform = roPlatform env + (iNT64Ty, mkLitINT64) + | platformWordSizeInBits platform < 64 + = (int64PrimTy, mkLitInt64Wrap) + | otherwise + = (intPrimTy , mkLitIntWrap) +doubleDecodeOp _ _ + = Nothing + -------------------------- {- Note [The litEq rule: converting equality to case] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1317,7 +1333,6 @@ builtinIntegerRules = rule_encodeFloat "encodeFloatInteger" encodeFloatIntegerName mkFloatLitFloat, rule_convert "floatFromInteger" floatFromIntegerName (\_ -> mkFloatLitFloat), rule_encodeFloat "encodeDoubleInteger" encodeDoubleIntegerName mkDoubleLitDouble, - rule_decodeDouble "decodeDoubleInteger" decodeDoubleIntegerName, rule_convert "doubleFromInteger" doubleFromIntegerName (\_ -> mkDoubleLitDouble), rule_rationalTo "rationalToFloat" rationalToFloatName mkFloatExpr, rule_rationalTo "rationalToDouble" rationalToDoubleName mkDoubleExpr, @@ -1390,9 +1405,6 @@ builtinIntegerRules = rule_encodeFloat str name op = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 2, ru_try = match_Integer_Int_encodeFloat op } - rule_decodeDouble str name - = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, - ru_try = match_decodeDouble } rule_XToIntegerToX str name toIntegerName = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, ru_try = match_XToIntegerToX toIntegerName } @@ -1747,22 +1759,6 @@ match_rationalTo mkLit _ id_unf _ [xl, yl] = Just (mkLit (fromRational (x % y))) match_rationalTo _ _ _ _ _ = Nothing -match_decodeDouble :: RuleFun -match_decodeDouble env id_unf fn [xl] - | Just (LitDouble x) <- exprIsLiteral_maybe id_unf xl - = case splitFunTy_maybe (idType fn) of - Just (_, res) - | Just [_lev1, _lev2, integerTy, intHashTy] <- tyConAppArgs_maybe res - -> case decodeFloat (fromRational x :: Double) of - (y, z) -> - Just $ mkCoreUbxTup [integerTy, intHashTy] - [Lit (mkLitInteger y integerTy), - Lit (mkLitInt (roPlatform env) (toInteger z))] - _ -> - pprPanic "match_decodeDouble: Id has the wrong type" - (ppr fn <+> dcolon <+> ppr (idType fn)) -match_decodeDouble _ _ _ _ = Nothing - match_XToIntegerToX :: Name -> RuleFun match_XToIntegerToX n _ _ _ [App (Var x) y] | idName x == n ===================================== libraries/integer-gmp/src/GHC/Integer/Type.hs ===================================== @@ -1618,7 +1618,6 @@ foreign import ccall unsafe "integer_gmp_invert" -- Conversions to/from floating point decodeDoubleInteger :: Double# -> (# Integer, Int# #) --- decodeDoubleInteger 0.0## = (# S# 0#, 0# #) #if WORD_SIZE_IN_BITS == 64 decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# S# m#, e# #) @@ -1626,7 +1625,7 @@ decodeDoubleInteger x = case decodeDouble_Int64# x of decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# int64ToInteger m#, e# #) #endif -{-# CONSTANT_FOLDED decodeDoubleInteger #-} +{-# INLINE decodeDoubleInteger #-} -- provided by GHC's RTS foreign import ccall unsafe "__int_encodeDouble" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3c86479ccadaa39688dd373325b0ac021efeb75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3c86479ccadaa39688dd373325b0ac021efeb75 You're receiving 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 24 13:11:44 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 24 Apr 2020 09:11:44 -0400 Subject: [Git][ghc/ghc][wip/T17775] Wibbles in response to Richard and Ryan reviews Message-ID: <5ea2e5903303_6167e5b4fc46901425@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 04e23aea by Simon Peyton Jones at 2020-04-24T14:02:02+01:00 Wibbles in response to Richard and Ryan reviews - - - - - 8 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/partial-sigs/should_compile/TypeFamilyInstanceLHS.stderr - testsuite/tests/polykinds/T9569.hs Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -262,6 +262,7 @@ tidyCoAxBndrsForUser :: TidyEnv -> [Var] -> (TidyEnv, [Var]) -- forall a _1 _2. F _1 [a] _2 = ... -- -- This is a rather disgusting function +-- See Note [Wildcard names] in GHC.Tc.Gen.HsType tidyCoAxBndrsForUser init_env tcvs = (tidy_env, reverse tidy_bndrs) where ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1873,12 +1873,17 @@ isTauTy (CoercionTy _) = False -- Not sure about this isAtomicTy :: Type -> Bool -- True if the type is just a single token, and can be printed compactly -isAtomicTy (TyVarTy {}) = True -isAtomicTy (LitTy {}) = True -isAtomicTy (TyConApp _ []) = True -isAtomicTy ty | isLiftedTypeKind ty = True -- Type prints compactly as * -isAtomicTy _ = False +-- Used when deciding how to lay out type error messages; see the +-- call in GHC.Tc.Errors +isAtomicTy (TyVarTy {}) = True +isAtomicTy (LitTy {}) = True +isAtomicTy (TyConApp _ []) = True +isAtomicTy ty | isLiftedTypeKind ty = True + -- 'Type' prints compactly as * + -- See GHC.Iface.Type.ppr_kind_type + +isAtomicTy _ = False {- %************************************************************************ ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -425,7 +425,7 @@ reportImplic ctxt implic@(Implic { ic_skols = tvs ; reportWanteds ctxt' tc_lvl wanted ; when (cec_warn_redundant ctxt) $ warnRedundantConstraints ctxt' tcl_env info' dead_givens - ; when bad_telescope $ reportBadTelescope ctxt tcl_env info tvs } + ; when bad_telescope $ reportBadTelescope ctxt' tcl_env info' tvs' } where tcl_env = ic_env implic insoluble = isInsolubleStatus status ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -336,7 +336,7 @@ tcHsSigType ctxt sig_ty ; (implic, ty) <- tc_hs_sig_type skol_info sig_ty (expectedKindInCtxt ctxt) -- Spit out the implication (and perhpas fail fast) - -- See Note [Kind-checking type signatures] in GHC.Tc.Solver + -- See Note [Failure in local type signatures] in GHC.Tc.Solver ; emitFlatConstraints (mkImplicWC (unitBag implic)) ; ty <- zonkTcType ty @@ -378,6 +378,7 @@ tc_hs_sig_type skol_info hs_sig_type ctxt_kind ; kvs <- kindGeneralizeSome should_gen ty1 -- Build an implication for any as-yet-unsolved kind equalities + -- See Note [Skolem escape in type signatures] ; implic <- buildTvImplication skol_info (kvs ++ spec_tkvs) tc_lvl wanted ; return (implic, mkInvForAllTys kvs ty1) } @@ -388,21 +389,28 @@ tcHsSigType is tricky. Consider (T11142) foo :: forall b. (forall k (a :: k). SameKind a b) -> () This is ill-kinded becuase of a nested skolem-escape. -That will show up as an un-solvable constraint in the implicaiton -returned by buildTvImplication in tc_hs_sig_type. +That will show up as an un-solvable constraint in the implication +returned by buildTvImplication in tc_hs_sig_type. See Note [Skolem +escape prevention] in GHC.Tc.Utils.TcType for why it is unsolvable +(the unification variable for b's kind is untouchable). Then, in GHC.Tc.Solver.emitFlatConstraints (called from tcHsSigType) we'll try to float out the constraint, be unable to do so, and fail. -See GHC.Tc.Solver Note [Failure in local type signatures]. +See GHC.Tc.Solver Note [Failure in local type signatures] for more +detail on this. The separation between tcHsSigType and tc_hs_sig_type is because tcClassSigType wants to use the latter, but *not* fail fast, because -there are skolems from the class decl which are in scope; but its fine +there are skolems from the class decl which are in scope; but it's fine not to because tcClassDecl1 has a solveEqualities wrapped around all the tcClassSigType calls. That's why tcHsSigType does emitFlatConstraints (which fails fast) but tcClassSigType just does emitImplication (which does not). Ugh. + +c.f. see also Note [Skolem escape and forall-types]. The difference +is that we don't need ot simplify at a forall type, only at the +top level of a signature. -} -- Does validity checking and zonking. @@ -411,7 +419,7 @@ tcStandaloneKindSig (L _ kisig) = case kisig of StandaloneKindSig _ (L _ name) ksig -> let ctxt = StandaloneKindSigCtxt name in addSigCtxt ctxt (hsSigType ksig) $ - do { mode <- mkMode KindLevel + do { mode <- mkTcTyMode KindLevel ; kind <- tc_top_lhs_type mode ksig (expectedKindInCtxt ctxt) ; checkValidType ctxt kind ; return (name, kind) } @@ -419,7 +427,7 @@ tcStandaloneKindSig (L _ kisig) = case kisig of tcTopLHsType :: LHsSigType GhcRn -> ContextKind -> TcM Type tcTopLHsType hs_ty ctxt_kind - = do { mode <- mkMode TypeLevel + = do { mode <- mkTcTyMode TypeLevel ; tc_top_lhs_type mode hs_ty ctxt_kind } tc_top_lhs_type :: TcTyMode -> LHsSigType GhcRn -> ContextKind -> TcM Type @@ -514,15 +522,14 @@ tcHsTypeApp :: LHsWcType GhcRn -> Kind -> TcM Type -- See Note [Recipe for checking a signature] in GHC.Tc.Gen.HsType tcHsTypeApp wc_ty kind | HsWC { hswc_ext = sig_wcs, hswc_body = hs_ty } <- wc_ty - = do { mode <- mkMode TypeLevel - ; let mode' = mode { mode_holes = HM_VTA } - -- See Note [Wildcards in visible type application] + = do { mode <- mkMode TypeLevel HM_VTA + -- HM_VTA: See Note [Wildcards in visible type application] ; ty <- addTypeCtxt hs_ty $ solveLocalEqualities "tcHsTypeApp" $ -- We are looking at a user-written type, very like a -- signature so we want to solve its equalities right now tcNamedWildCardBinders sig_wcs $ \ _ -> - tc_lhs_type mode' hs_ty kind + tc_lhs_type mode hs_ty kind -- We do not kind-generalize type applications: we just -- instantiate with exactly what the user says. @@ -577,13 +584,11 @@ tcFamTyPats fam_tc hs_pats = do { traceTc "tcFamTyPats {" $ vcat [ ppr fam_tc, text "arity:" <+> ppr fam_arity ] - - ; mode <- mkMode TypeLevel + ; mode <- mkMode TypeLevel HM_FamPat + -- HM_FamPat: See Note [Wildcards in family instances] in + -- GHC.Rename.Module ; let fun_ty = mkTyConApp fam_tc [] - mode' = mode { mode_holes = HM_FamPat } - -- See Note [Wildcards in family instances] in - -- GHC.Rename.Module - ; (fam_app, res_kind) <- tcInferTyApps mode' lhs_fun fun_ty hs_pats + ; (fam_app, res_kind) <- tcInferTyApps mode lhs_fun fun_ty hs_pats ; traceTc "End tcFamTyPats }" $ vcat [ ppr fam_tc, text "res_kind:" <+> ppr res_kind ] @@ -624,7 +629,7 @@ tcCheckLHsType hs_ty exp_kind tcInferLHsType :: LHsType GhcRn -> TcM (TcType, TcKind) -- Called from outside: set the context tcInferLHsType hs_ty = addTypeCtxt hs_ty $ - do { mode <- mkMode TypeLevel + do { mode <- mkTcTyMode TypeLevel ; tc_infer_lhs_type mode hs_ty } -- Like tcInferLHsType, but use it in a context where type synonyms and type families @@ -633,7 +638,7 @@ tcInferLHsTypeUnsaturated :: LHsType GhcRn -> TcM (TcType, TcKind) tcInferLHsTypeUnsaturated hs_ty | Just (hs_fun_ty, hs_args) <- splitHsAppTys (unLoc hs_ty) = addTypeCtxt hs_ty $ - do { mode <- mkMode TypeLevel + do { mode <- mkTcTyMode TypeLevel ; (fun_ty, _ki) <- tcInferAppHead mode hs_fun_ty ; tcInferTyApps_nosat mode hs_fun_ty fun_ty hs_args } -- Notice the 'nosat'; do not instantiate trailing @@ -687,30 +692,49 @@ concern things that the renamer can't handle. -- -- This data type is purely local, not exported from this module data TcTyMode - = TcTyMode { mode_tyki:: TypeOrKind + = TcTyMode { mode_tyki :: TypeOrKind - -- See Note [Level for anonymous wildcards] + -- See Note [Levels for wildcards] , mode_lvl :: TcLevel , mode_holes :: HoleMode - -- True <=> emit a hole constraints for an - -- anonymous wildcard } -data HoleMode = HM_Sig -- Type signatures: f :: _ -> Int +-- HoleMode says how to treat the occurrences +-- of anonymous wildcards; see tcAnonWildCardOcc +data HoleMode = HM_NoHoles -- No wildcard expected + | HM_Sig -- Partial type signatures: f :: _ -> Int | HM_FamPat -- Family instances: F _ Int = Bool | HM_VTA -- Visible type and kind application: -- f @(Maybe _) -- Maybe @(_ -> _) -mkMode :: TypeOrKind -> TcM TcTyMode -mkMode tyki +holesOK :: HoleMode -> Bool +-- True <=> it's ok to encounter a hole +-- Should have been checked by the renamer +holesOK HM_NoHoles = False +holesOK _ = True + +mkTcTyMode :: TypeOrKind -> TcM TcTyMode +mkTcTyMode tyki = mkMode tyki HM_NoHoles + +mkMode :: TypeOrKind -> HoleMode -> TcM TcTyMode +mkMode tyki hm = do { lvl <- getTcLevel ; return (TcTyMode { mode_tyki = tyki , mode_lvl = lvl - , mode_holes = HM_Sig }) } + , mode_holes = hm }) } + +instance Outputable HoleMode where + ppr HM_NoHoles = text "HM_NoHoles" + ppr HM_Sig = text "HM_Sig" + ppr HM_FamPat = text "HM_FamPat" + ppr HM_VTA = text "HM_VTA" instance Outputable TcTyMode where - ppr = ppr . mode_tyki + ppr (TcTyMode { mode_tyki = tyki, mode_lvl = lvl, mode_holes = hm }) + = text "TcTyMode" <+> braces (sep [ ppr tyki <> comma + , ppr hm <> comma + , text "lvl:" <> ppr lvl ]) {- Note [Bidirectional type checking] @@ -826,7 +850,7 @@ tc_infer_hs_type mode other_ty ------------------------------------------ tcLHsType :: LHsType GhcRn -> TcKind -> TcM TcType tcLHsType hs_ty exp_kind - = do { mode <- mkMode TypeLevel + = do { mode <- mkTcTyMode TypeLevel ; tc_lhs_type mode hs_ty exp_kind } tc_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType @@ -1630,11 +1654,11 @@ tcHsMbContext Nothing = return [] tcHsMbContext (Just cxt) = tcHsContext cxt tcHsContext :: LHsContext GhcRn -> TcM [PredType] -tcHsContext cxt = do { mode <- mkMode TypeLevel +tcHsContext cxt = do { mode <- mkTcTyMode TypeLevel ; tc_hs_context mode cxt } tcLHsPredType :: LHsType GhcRn -> TcM PredType -tcLHsPredType pred = do { mode <- mkMode TypeLevel +tcLHsPredType pred = do { mode <- mkTcTyMode TypeLevel ; tc_lhs_pred mode pred } tc_hs_context :: TcTyMode -> LHsContext GhcRn -> TcM [PredType] @@ -1877,13 +1901,16 @@ newNamedWildTyVar _name -- Currently ignoring the "_x" wildcard name used in t tcAnonWildCardOcc :: TcTyMode -> HsType GhcRn -> Kind -> TcM TcType tcAnonWildCardOcc (TcTyMode { mode_lvl = lvl, mode_holes = hole_mode }) ty exp_kind - = do { kv_details <- newTauTvDetailsAtLevel lvl + -- mode_lvl field: see Note [Checking partial type signatures] + -- esp the bullet on nested forall types + = ASSERT2( holesOK hole_mode, ppr ty ) + do { kv_details <- newTauTvDetailsAtLevel lvl ; kv_name <- newMetaTyVarName (fsLit "k") ; wc_details <- newTauTvDetailsAtLevel lvl ; wc_name <- newMetaTyVarName (fsLit wc_nm) ; let kv = mkTcTyVar kv_name liftedTypeKind kv_details wc_kind = mkTyVarTy kv - ; let wc_tv = mkTcTyVar wc_name wc_kind wc_details + wc_tv = mkTcTyVar wc_name wc_kind wc_details ; traceTc "tcAnonWildCardOcc" (ppr lvl <+> ppr emit_holes) ; when emit_holes $ @@ -1899,8 +1926,8 @@ tcAnonWildCardOcc (TcTyMode { mode_lvl = lvl, mode_holes = hole_mode }) where -- See Note [Wildcard names] wc_nm = case hole_mode of - HM_FamPat -> "_" HM_Sig -> "w" + HM_FamPat -> "_" HM_VTA -> "w" emit_holes = case hole_mode of @@ -1916,10 +1943,10 @@ wildcard "w", not "_". If we use the latter, we get messages like which is a bit confusing. I prefer Found type wildcard ‘_’ standing for ‘w0’ -However, on the LHS of family instances we switch hole emission -off (see Note [Wildcards in family instances] in GHC.Rename.Module -and tcFamTyPats above. And for family insatnce we prefer to use "_" -so that we can pretty-print the LHS as +However, on the LHS of family instances we switch hole emission off +(see Note [Wildcards in family instances] in GHC.Rename.Module) by +using HM_FamPat in tcFamTyPats above. And for family insatnce we +prefer to use "_" so that we can pretty-print the LHS as F _ Int _ = ... not F w1 Int w2 = ... @@ -1927,7 +1954,7 @@ There is some unsavory magic, relying on that underscore, in GHC.Core.Coercion.tidyCoAxBndrsForUser. So we hackily use the mode_holes flag to control the name used -for wildcards. Ugh. But it works +for wildcards. Ugh. But it works. Note [Wildcards in visible kind application] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3295,7 +3322,7 @@ tcHsPartialSigType ctxt sig_ty , hsib_body = hs_ty } <- ib_ty , (explicit_hs_tvs, L _ hs_ctxt, hs_tau) <- splitLHsSigmaTyInvis hs_ty = addSigCtxt ctxt hs_ty $ - do { mode <- mkMode TypeLevel + do { mode <- mkMode TypeLevel HM_Sig ; (implicit_tvs, (explicit_tvs, (wcs, wcx, theta, tau))) <- solveLocalEqualities "tcHsPartialSigType" $ tcNamedWildCardBinders sig_wcs $ \ wcs -> @@ -3323,8 +3350,8 @@ tcHsPartialSigType ctxt sig_ty ; emitNamedWildCardHoleConstraints wcs -- Zonk, so that any nested foralls can "see" their occurrences - -- See Note [Checking partial type signatures], in - -- the bullet on Nested foralls. + -- See Note [Checking partial type signatures], and in particular + -- Note [Levels for wildcards] ; implicit_tvs <- mapM zonkTcTyVarToTyVar implicit_tvs ; explicit_tvs <- mapM zonkTcTyVarToTyVar explicit_tvs ; theta <- mapM zonkTcType theta @@ -3396,23 +3423,7 @@ we do the following g x = True It's really as if we'd written two distinct signatures. -* Nested foralls. Consider - f :: forall b. (forall a. a -> _) -> b - We do /not/ allow the "_" to be instantiated to 'a'; but we do - (as before) allow it to be instantiated to the (top level) 'b'. - Why not? Because suppose - f x = (x True, x 'c') - We must instantiate that (forall a. a -> _) when typechecking - f's body, so we must know precisely where all the a's are; they - must not be hidden under (filled-in) unification variables! - - We achieve this: - - For /named/ wildcards, we create them at the outer level, and push - the level when we go inside a forall. So now the unification - variable for the "_" can't unify with 'a'. - - For /anonymous/ wildcards, we float them all out in - floatKindEqualities, and promote them in emitFlatConstraints. - See Note [Failure in local type signatures] in GHC.Tc.Solver. +* Nested foralls. See Note [Levels for wildcards] * Just as for ordinary signatures, we must zonk the type after kind-checking it, to ensure that all the nested forall binders can @@ -3423,6 +3434,36 @@ we do the following foo :: (forall a. (Show a => blah) |> Refl) -> _ and that Refl cast messed things up. See #18062. +Note [Levels for wildcards] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + f :: forall b. (forall a. a -> _) -> b +We do /not/ allow the "_" to be instantiated to 'a'; although we do +(as before) allow it to be instantiated to the (top level) 'b'. +Why not? Suppose + f x = (x True, x 'c') + +During typecking the RHS we must instantiate that (forall a. a -> _), +so we must know /precisely/ where all the a's are; they must not be +hidden under (possibly-not-yet-filled-in) unification variables! + +We achieve this as follows: + +- For /named/ wildcards such sas + g :: forall b. (forall la. a -> _x) -> b + there is no problem: we create them at the outer level (ie the + ambient level of teh signature itself), and push the level when we + go inside a forall. So now the unification variable for the "_x" + can't unify with skolem 'a'. + +- For /anonymous/ wildcards, such as 'f' above, we carry the ambient + level of the signature to the hole in the mode_lvl field of + TcTyMode. Then, in tcAnonWildCardOcc we us that level (and /not/ + the level ambient at the occurrence of "_") to create the + unificaiton variable for the wildcard. That is the sole + purpose of the mode_lvl field: to transport the ambient level + of the signature down to the anonymous wildcard occurrences. + Note [Extra-constraint holes in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -3597,7 +3638,7 @@ It does sort checking and desugaring at the same time, in one single pass. tcLHsKindSig :: UserTypeCtxt -> LHsKind GhcRn -> TcM Kind tcLHsKindSig ctxt hs_kind - = do { mode <- mkMode KindLevel + = do { mode <- mkTcTyMode KindLevel ; tc_lhs_kind_sig mode ctxt hs_kind } tc_lhs_kind_sig :: TcTyMode -> UserTypeCtxt -> LHsKind GhcRn -> TcM Kind ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -98,7 +98,7 @@ tcMatchesFun fn@(L _ fun_name) matches exp_ty ; checkArgs fun_name matches ; matchExpectedFunTys herald ctxt arity exp_ty $ \ pat_tys rhs_ty -> - -- NB: exp_type may be polymoprhic, but + -- NB: exp_type may be polymorphic, but -- matchExpectedFunTys can cope with that tcMatches match_ctxt pat_tys rhs_ty matches } where ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -163,7 +163,7 @@ matchExpectedFunTys herald ctx arity orig_ty thing_inside go acc_arg_tys n ty' ; return (wrap_gen <.> wrap_res, result) } - -- No more args; do thisbefore tcView, so + -- No more args; do this /before/ tcView, so -- that we do not unnecessarily unwrap synonyms go acc_arg_tys 0 rho_ty = do { result <- thing_inside (reverse acc_arg_tys) (mkCheckExpType rho_ty) ===================================== testsuite/tests/partial-sigs/should_compile/TypeFamilyInstanceLHS.stderr ===================================== @@ -4,12 +4,12 @@ TYPE CONSTRUCTORS type family F{2} :: * -> * -> * roles nominal nominal COERCION AXIOMS - axiom TypeFamilyInstanceLHS.D:R:FBoolw :: F Bool w = Bool - axiom TypeFamilyInstanceLHS.D:R:FIntw :: F Int w = Int + axiom TypeFamilyInstanceLHS.D:R:FBool_1 :: F Bool _1 = Bool + axiom TypeFamilyInstanceLHS.D:R:FInt_1 :: F Int _1 = Int FAMILY INSTANCES - type instance F Int w = Int + type instance F Int _ = Int -- Defined at TypeFamilyInstanceLHS.hs:7:15 - type instance F Bool w = Bool + type instance F Bool _ = Bool -- Defined at TypeFamilyInstanceLHS.hs:8:15 Dependent modules: [] Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, ===================================== testsuite/tests/polykinds/T9569.hs ===================================== @@ -23,16 +23,20 @@ instance (Deferrable c1, Deferrable c2) => Deferrable (c1,c2) where {- Notes Apr 2020. ~~~~~~~~~~~~~~~~~ -Wow, this is horrible! If you say +Note the careful type for deferPair! You can also say deferPair :: (Deferrable c1, Deferrable c2, d ~ (c1,c2)) => Proxy (c1,c2) -> (d => a) -> a -then it all works. The point is that + +but NOT + +deferPair :: (Deferrable c1, Deferrable c2) + => Proxy (c1,c2) -> ((c1,c2) => a) -> a + +The point is that (c1,c2) => a is short for c1 => c2 => a -and we have no source language notation for the form that takes -a single constraint tuple. -} {- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04e23aea46b26442dca59f4bcf57d5d91a775da0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04e23aea46b26442dca59f4bcf57d5d91a775da0 You're receiving 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 24 13:21:07 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 24 Apr 2020 09:21:07 -0400 Subject: [Git][ghc/ghc][wip/T17775] Wibble Message-ID: <5ea2e7c351de0_61673f81afeb5fbc69061ae@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: f767c285 by Simon Peyton Jones at 2020-04-24T14:20:08+01:00 Wibble - - - - - 1 changed file: - testsuite/tests/simplCore/should_compile/T17930.stderr Changes: ===================================== testsuite/tests/simplCore/should_compile/T17930.stderr ===================================== @@ -1,99 +1,2 @@ - -==================== Specialise ==================== -Result size of Specialise - = {terms: 90, types: 84, coercions: 10, joins: 0/0} - --- RHS size: {terms: 32, types: 27, coercions: 3, joins: 0/0} $sfoo :: (?b::Bool) => String -> [Char] $sfoo - = \ ($dIP :: ?b::Bool) (x :: String) -> - case $dIP - `cast` (GHC.Classes.N:IP[0] <"b">_N _N - :: (?b::Bool) ~R# Bool) - of { - False -> - GHC.Base.build - @Char - (\ (@b) (c :: Char -> b -> b) (n :: b) -> - GHC.Base.foldr - @Char - @b - c - (GHC.CString.unpackFoldrCString# @b "."# c n) - (show @String GHC.Show.$fShow[]_$s$fShow[]1 x)); - True -> - GHC.Base.build - @Char - (\ (@b) (c :: Char -> b -> b) (n :: b) -> - GHC.Base.foldr - @Char - @b - c - (GHC.CString.unpackFoldrCString# @b "!"# c n) - (show @String GHC.Show.$fShow[]_$s$fShow[]1 x)) - } - --- RHS size: {terms: 34, types: 31, coercions: 3, joins: 0/0} -foo :: forall a. (?b::Bool, Show a) => a -> String -foo - = \ (@a) ($dIP :: ?b::Bool) ($dShow :: Show a) (x :: a) -> - case $dIP - `cast` (GHC.Classes.N:IP[0] <"b">_N _N - :: (?b::Bool) ~R# Bool) - of { - False -> - GHC.Base.build - @Char - (\ (@b) (c :: Char -> b -> b) (n :: b) -> - GHC.Base.foldr - @Char - @b - c - (GHC.CString.unpackFoldrCString# @b "."# c n) - (show @a $dShow x)); - True -> - GHC.Base.build - @Char - (\ (@b) (c :: Char -> b -> b) (n :: b) -> - GHC.Base.foldr - @Char - @b - c - (GHC.CString.unpackFoldrCString# @b "!"# c n) - (show @a $dShow x)) - } - --- RHS size: {terms: 7, types: 5, coercions: 4, joins: 0/0} -str :: String -str - = foo - @String - (GHC.Types.True - `cast` (Sym (GHC.Classes.N:IP[0] <"b">_N _N) - :: Bool ~R# (?b::Bool))) - GHC.Show.$fShow[]_$s$fShow[]1 - (GHC.Base.build - @Char (\ (@b) -> GHC.CString.unpackFoldrCString# @b "Hello"#)) - --- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} -$trModule :: GHC.Prim.Addr# -$trModule = "main"# - --- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} -$trModule :: GHC.Types.TrName -$trModule = GHC.Types.TrNameS $trModule - --- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} -$trModule :: GHC.Prim.Addr# -$trModule = "T17930"# - --- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} -$trModule :: GHC.Types.TrName -$trModule = GHC.Types.TrNameS $trModule - --- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} -T17930.$trModule :: GHC.Types.Module -T17930.$trModule = GHC.Types.Module $trModule $trModule - - - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f767c28518319c471f432c2f45fe6661bf2d255e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f767c28518319c471f432c2f45fe6661bf2d255e You're receiving 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 24 14:44:42 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 24 Apr 2020 10:44:42 -0400 Subject: [Git][ghc/ghc][wip/T17775] 2 commits: Wibbles Message-ID: <5ea2fb5ae8748_61673f81cd0d79186926140@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 9c1f41ce by Simon Peyton Jones at 2020-04-24T15:42:26+01:00 Wibbles - - - - - 8095fb16 by Simon Peyton Jones at 2020-04-24T15:43:26+01:00 Get the right version of Haddock (Thanks Ryan.) - - - - - 2 changed files: - compiler/GHC/Tc/Solver.hs - utils/haddock Changes: ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -160,17 +160,19 @@ simplifyTop wanteds -- should generally bump the TcLevel to make sure that this run of the solver -- doesn't affect anything lying around. solveLocalEqualities :: String -> TcM a -> TcM a +-- Note [Failure in local type signatures] solveLocalEqualities callsite thing_inside = do { (wanted, res) <- solveLocalEqualitiesX callsite thing_inside ; emitFlatConstraints wanted ; return res } emitFlatConstraints :: WantedConstraints -> TcM () +-- See Note [Failure in local type signatures] emitFlatConstraints wanted = do { wanted <- TcM.zonkWC wanted ; case floatKindEqualities wanted of Nothing -> do { traceTc "emitFlatConstraints: failing" (ppr wanted) - ; emitConstraints wanted + ; emitConstraints wanted -- So they get reported! ; failM } Just simple_wanteds -> do { _ <- promoteTyVarSet $ tyCoVarsOfCts simple_wanteds @@ -201,10 +203,11 @@ floatKindEqualities wc = float_wc emptyVarSet wc = Nothing -- A short cut /plus/ we must keep track of IC_BadTelescope | otherwise = do { cts <- float_wc new_trapping_tvs (ic_wanted imp) - ; unless (isEmptyBag cts || ic_no_eqs imp) $ + ; when (not (isEmptyBag cts) && not (ic_no_eqs imp)) $ Nothing - -- Don't float out past local equalities - -- C.f GHC.Tc.Solver.approximateWC + -- If there are some constraints to float out, but we can't + -- because we don't float out past local equalities + -- (c.f GHC.Tc.Solver.approximateWC), then fail ; return cts } where new_trapping_tvs = trapping_tvs `extendVarSetList` ic_skols imp @@ -215,7 +218,7 @@ floatKindEqualities wc = float_wc emptyVarSet wc When kind checking a type signature, we like to fail fast if we can't solve all the kind equality constraints: see Note [Fail fast on kind errors]. But what about /local/ type signatures, mentioning in-scope -type varaibles for which there might be given equalities. Here's +type variables for which there might be given equalities. Here's an example (T15076b): class (a ~ b) => C a b @@ -275,7 +278,7 @@ So here's the plan: * Note that this float-and-promote step means that anonymous wildcards get floated to top level, as we want; see - Note [Checking partial type signatures] in GHC.Tc.Geh.HsType. + Note [Checking partial type signatures] in GHC.Tc.Gen.HsType. All this is done: ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 5ec817a3e41b7eaa50c74701ab2d7642df86464c +Subproject commit 20bf93490b37c0410d85a0ad4d38f9ddc2253589 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f767c28518319c471f432c2f45fe6661bf2d255e...8095fb16c3d98a4a1d3165d82ac0f2af689481dd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f767c28518319c471f432c2f45fe6661bf2d255e...8095fb16c3d98a4a1d3165d82ac0f2af689481dd You're receiving 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 24 17:13:51 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 13:13:51 -0400 Subject: [Git][ghc/ghc][wip/runRW] runRW Message-ID: <5ea31e4f6177e_6167125d038869787a5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 33147251 by Ben Gamari at 2020-04-24T17:13:34+00:00 runRW - - - - - 4 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -246,7 +246,6 @@ basicKnownKeyNames -- See Note [TyConRepNames for non-wired-in TyCons] ioTyConName, ioDataConName, runMainIOName, - runRWName, -- Type representation types trModuleTyConName, trModuleDataConName, @@ -912,9 +911,8 @@ and it's convenient to write them all down in one place. wildCardName :: Name wildCardName = mkSystemVarName wildCardKey (fsLit "wild") -runMainIOName, runRWName :: Name +runMainIOName :: Name runMainIOName = varQual gHC_TOP_HANDLER (fsLit "runMainIO") runMainKey -runRWName = varQual gHC_MAGIC (fsLit "runRW#") runRWKey orderingTyConName, ordLTDataConName, ordEQDataConName, ordGTDataConName :: Name orderingTyConName = tcQual gHC_TYPES (fsLit "Ordering") orderingTyConKey ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -875,15 +875,29 @@ lintCoreExpr e@(App _ _) , arg_ty1 : arg_ty2 : arg3 : rest <- args = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 + -- Note [Linting of runRW#] + -- ~~~~~~~~~~~~~~~~~~~~~~~~ + -- runRW# has some very peculiar behavior (see Note [runRW magic] in + -- GHC.CoreToStg.Prep) which CoreLint must accommodate. + -- -- The simplifier pushes casts out of the continuation lambda; -- consequently we need to handle the case that the continuation is a -- cast lambda. See Note [Casts and lambdas] in -- GHC.Core.Opt.Simplify.Utils. - ; arg3_ty <- case arg3 of - Cast expr co -> do - expr_ty <- lintJoinLams 1 (Just fun) expr - lintCastExpr expr expr_ty co - _ -> lintJoinLams 1 (Just fun) arg3 + -- + -- In the event that the continuation is headed by a lambda (which + -- will bind the State# token) we can safely allow calls to join + -- points since CorePrep is going to apply the continuation to + -- RealWorld. + ; let lintRunRWCont :: CoreArg -> LintM LintedType + lintRunRWCont (Cast expr co) = do + ty <- lintRunRWCont expr + lintCastExpr expr ty co + lintRunRWCont expr@(Lam _ _) = do + lintJoinLams 1 (Just fun) expr + lintRunRWCont other = markAllJoinsBad $ lintCoreExpr other + -- TODO: Look through ticks? + ; arg3_ty <- lintRunRWCont arg3 ; app_ty <- lintValApp arg3 fun_ty2 arg3_ty ; lintCoreArgs app_ty rest } ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -974,8 +974,43 @@ pragma. It is levity-polymorphic. => (State# RealWorld -> (# State# RealWorld, o #)) -> (# State# RealWorld, o #) -It needs no special treatment in GHC except this special inlining here -in CorePrep (and in GHC.CoreToByteCode). +It's correctness needs no special treatment in GHC except this special inlining +here in CorePrep (and in GHC.CoreToByteCode). + +However, there are a variety of optimisation opportunities that the simplifier +takes advantage of. See Note [Simplification of runRW#]. + + +Note [Simplification of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the program, + + case runRW# (\s -> let n = I# 42# in n) of + I# n# -> f n# + +There is no reason why we should allocate an I# constructor given that we +immediately destructure it. To avoid this the simplifier will push strict +contexts into runRW's continuation. That is, it transforms + + K[ runRW# @r @ty cont ] + ~> + runRW# @r @ty K[cont] + +This has a few interesting implications. Consider, for instance, this program: + + join j = ... + in case runRW# @r @ty cont of + result -> jump j result + +Performing the transform described above would result in: + + join j = ... + in runRW# @r @ty ( + case cont of in + result -> jump j result + +TODO + -- --------------------------------------------------------------------------- -- CpeArg: produces a result satisfying CpeArg ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -147,7 +147,7 @@ wiredInIds ++ errorIds -- Defined in GHC.Core.Make magicIds :: [Id] -- See Note [magicIds] -magicIds = [lazyId, oneShotId, noinlineId] +magicIds = [lazyId, oneShotId, noinlineId, runRWId] ghcPrimIds :: [Id] -- See Note [ghcPrimIds (aka pseudoops)] ghcPrimIds @@ -1323,10 +1323,11 @@ magicDictName = mkWiredInIdName gHC_PRIM (fsLit "magicDict") magicDict coerceName = mkWiredInIdName gHC_PRIM (fsLit "coerce") coerceKey coerceId proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHashKey proxyHashId -lazyIdName, oneShotName, noinlineIdName :: Name +lazyIdName, oneShotName, noinlineIdName, runRWIdName :: Name lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId oneShotName = mkWiredInIdName gHC_MAGIC (fsLit "oneShot") oneShotKey oneShotId noinlineIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinline") noinlineIdKey noinlineId +runRWIdName = mkWiredInIdName gHC_MAGIC (fsLit "runRW#") runRWKey runRWId ------------------------------------------------ proxyHashId :: Id @@ -1409,6 +1410,13 @@ oneShotId = pcMiscPrelId oneShotName ty info , body, x'] $ Var body `App` Var x +runRWId :: Id -- See Note [runRW magic] in GHC.CoreToStg.Prep +runRWId = pcMiscPrelId runRWIdName ty info + where + info = noCafIdInfo `setStrictnessInfo` mkClosedStrictSig [strictApply1Dmd] topDiv + ty = mkSpecForAllTys [runtimeRep1TyVar, openAlphaTyVar] + $ mkVisFunTy (realWorldStatePrimTy `mkVisFunTy` openAlphaTy) openAlphaTy + -------------------------------------------------------------------------------- magicDictId :: Id -- See Note [magicDictId magic] magicDictId = pcMiscPrelId magicDictName ty info View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/331472515fae6011d25708ba4503a2ff68dbb47e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/331472515fae6011d25708ba4503a2ff68dbb47e You're receiving 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 24 18:51:02 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 14:51:02 -0400 Subject: [Git][ghc/ghc][wip/runRW] runRW Message-ID: <5ea33516bad7f_61673f81cd689d4869826e5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: a5d42156 by Ben Gamari at 2020-04-24T18:29:33+00:00 runRW - - - - - 5 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -246,7 +246,6 @@ basicKnownKeyNames -- See Note [TyConRepNames for non-wired-in TyCons] ioTyConName, ioDataConName, runMainIOName, - runRWName, -- Type representation types trModuleTyConName, trModuleDataConName, @@ -912,9 +911,8 @@ and it's convenient to write them all down in one place. wildCardName :: Name wildCardName = mkSystemVarName wildCardKey (fsLit "wild") -runMainIOName, runRWName :: Name +runMainIOName :: Name runMainIOName = varQual gHC_TOP_HANDLER (fsLit "runMainIO") runMainKey -runRWName = varQual gHC_MAGIC (fsLit "runRW#") runRWKey orderingTyConName, ordLTDataConName, ordEQDataConName, ordGTDataConName :: Name orderingTyConName = tcQual gHC_TYPES (fsLit "Ordering") orderingTyConKey ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -764,6 +764,40 @@ we will check any unfolding after it has been unfolded; checking the unfolding beforehand is merely an optimization, and one that actively hurts us here. +Note [Linting of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~ +runRW# has some very peculiar behavior (see Note [runRW magic] in +GHC.CoreToStg.Prep) which CoreLint must accommodate. + +As described in Note [Casts and lambdas] in +GHC.Core.Opt.Simplify.Utils, the simplifier pushes casts out of +lambdas. Concretely, the simplifier will transform + + runRW# @r @ty (\s -> expr `cast` co) + +into + + runRW# @r @ty ((\s -> expr) `cast` co) + +Consequently we need to handle the case that the continuation is a +cast of a lambda. See Note [Casts and lambdas] in +GHC.Core.Opt.Simplify.Utils. + +In the event that the continuation is headed by a lambda (which +will bind the State# token) we can safely allow calls to join +points since CorePrep is going to apply the continuation to +RealWorld. + +In the case that the continuation is not a lambda we lint the +continuation disallowing join points, to rule out things like, + + join j = ... + in runRW# @r @ty ( + let x = jump j + in x + ) + + ************************************************************************ * * \subsection[lintCoreExpr]{lintCoreExpr} @@ -875,15 +909,16 @@ lintCoreExpr e@(App _ _) , arg_ty1 : arg_ty2 : arg3 : rest <- args = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 - -- The simplifier pushes casts out of the continuation lambda; - -- consequently we need to handle the case that the continuation is a - -- cast lambda. See Note [Casts and lambdas] in - -- GHC.Core.Opt.Simplify.Utils. - ; arg3_ty <- case arg3 of - Cast expr co -> do - expr_ty <- lintJoinLams 1 (Just fun) expr - lintCastExpr expr expr_ty co - _ -> lintJoinLams 1 (Just fun) arg3 + -- See Note [Linting of runRW#] + ; let lintRunRWCont :: CoreArg -> LintM LintedType + lintRunRWCont (Cast expr co) = do + ty <- lintRunRWCont expr + lintCastExpr expr ty co + lintRunRWCont expr@(Lam _ _) = do + lintJoinLams 1 (Just fun) expr + lintRunRWCont other = markAllJoinsBad $ lintCoreExpr other + -- TODO: Look through ticks? + ; arg3_ty <- lintRunRWCont arg3 ; app_ty <- lintValApp arg3 fun_ty2 arg3_ty ; lintCoreArgs app_ty rest } ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -403,7 +403,8 @@ lvlApp :: LevelEnv -> (CoreExprWithFVs, [CoreExprWithFVs]) -- Input application -> LvlM LevelledExpr -- Result expression lvlApp env orig_expr ((_,AnnVar fn), args) - -- TODO: runRW#'s continuation must remain a join point; don't float! + -- Try to ensure that runRW#'s continuation isn't floated out. + -- See Note [Simplification of runRW#]. | fn `hasKey` runRWKey = do { args' <- mapM (lvlExpr env) args ; return (foldl' App (lookupVar env fn) args') } ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -974,8 +974,78 @@ pragma. It is levity-polymorphic. => (State# RealWorld -> (# State# RealWorld, o #)) -> (# State# RealWorld, o #) -It needs no special treatment in GHC except this special inlining here -in CorePrep (and in GHC.CoreToByteCode). +It's correctness needs no special treatment in GHC except this special inlining +here in CorePrep (and in GHC.CoreToByteCode). + +However, there are a variety of optimisation opportunities that the simplifier +takes advantage of. See Note [Simplification of runRW#]. + + +Note [Simplification of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the program, + + case runRW# (\s -> let n = I# 42# in n) of + I# n# -> f n# + +There is no reason why we should allocate an I# constructor given that we +immediately destructure it. To avoid this the simplifier will push strict +contexts into runRW's continuation. That is, it transforms + + K[ runRW# @r @ty cont ] + ~> + runRW# @r @ty K[cont] + +This has a few interesting implications. Consider, for instance, this program: + + join j = ... + in case runRW# @r @ty cont of + result -> jump j result + +Performing the transform described above would result in: + + join j x = ... + in runRW# @r @ty (\s -> + case cont of in + result -> jump j result + ) + +If runRW# were a "normal" function this call to join point j would not be +allowed in its continuation argument. However, since runRW# is inlined (as +described in Note [runRW magic] above), this is completely fine. + +Moreover, it's helpful to ensure that runRW's continuation isn't floated out +(since doing so would then require a call, whereas we would otherwise end up +with straight-line). Consequently, GHC.Core.Opt.SetLevels.lvlApp has special +treatment for runRW# applications, ensure the arguments are not floated if +MFEs. + +Consequently, Core Lint has some special treatment to allow this behavior (see +Note [Linting of runRW#]). + +Other considered designs +------------------------ + +One design that was rejected was to *require* that runRW#'s continuation be +headed by a lambda. However, this proved to be quite fragile. For instance, +SetLevels is very eager to float bottoming expressions. For instance given +something of the form, + + runRW# @r @ty (\s -> case expr of x -> undefined) + +SetLevels will see that the body the lambda is bottoming and will consequently +float it to the top-level (assuming expr has no free coercion variables which +prevent this). We therefore end up with + + runRW# @r @ty (\s -> lvl s) + +Which the simplifier will beta reduce, leaving us with + + runRW# @r @ty lvl + +Breaking our desired invariant. Ultimately we decided to simply accept that +the continuation may not be a manifest lambda. + -- --------------------------------------------------------------------------- -- CpeArg: produces a result satisfying CpeArg ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -147,7 +147,7 @@ wiredInIds ++ errorIds -- Defined in GHC.Core.Make magicIds :: [Id] -- See Note [magicIds] -magicIds = [lazyId, oneShotId, noinlineId] +magicIds = [lazyId, oneShotId, noinlineId, runRWId] ghcPrimIds :: [Id] -- See Note [ghcPrimIds (aka pseudoops)] ghcPrimIds @@ -1323,10 +1323,11 @@ magicDictName = mkWiredInIdName gHC_PRIM (fsLit "magicDict") magicDict coerceName = mkWiredInIdName gHC_PRIM (fsLit "coerce") coerceKey coerceId proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHashKey proxyHashId -lazyIdName, oneShotName, noinlineIdName :: Name +lazyIdName, oneShotName, noinlineIdName, runRWIdName :: Name lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId oneShotName = mkWiredInIdName gHC_MAGIC (fsLit "oneShot") oneShotKey oneShotId noinlineIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinline") noinlineIdKey noinlineId +runRWIdName = mkWiredInIdName gHC_MAGIC (fsLit "runRW#") runRWKey runRWId ------------------------------------------------ proxyHashId :: Id @@ -1409,6 +1410,13 @@ oneShotId = pcMiscPrelId oneShotName ty info , body, x'] $ Var body `App` Var x +runRWId :: Id -- See Note [runRW magic] in GHC.CoreToStg.Prep +runRWId = pcMiscPrelId runRWIdName ty info + where + info = noCafIdInfo `setStrictnessInfo` mkClosedStrictSig [strictApply1Dmd] topDiv + ty = mkSpecForAllTys [runtimeRep1TyVar, openAlphaTyVar] + $ mkVisFunTy (realWorldStatePrimTy `mkVisFunTy` openAlphaTy) openAlphaTy + -------------------------------------------------------------------------------- magicDictId :: Id -- See Note [magicDictId magic] magicDictId = pcMiscPrelId magicDictName ty info View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5d42156a0581bf7696a6ffd7c2cc250247d48a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5d42156a0581bf7696a6ffd7c2cc250247d48a0 You're receiving 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 24 19:44:02 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 15:44:02 -0400 Subject: [Git][ghc/ghc][wip/runRW] 38 commits: Derive Ord instance for Extension Message-ID: <5ea34182ce96_61673f813dcf07f86986153@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - 084d2198 by Simon Peyton Jones at 2020-04-24T15:12:27-04:00 Make Lint check return type of a join point Consider join x = rhs in body It's important that the type of 'rhs' is the same as the type of 'body', but Lint wasn't checking that invariant. Now it does! This was exposed by investigation into !3113. - - - - - fb193421 by Simon Peyton Jones at 2020-04-24T15:13:34-04:00 Do not float join points in exprIsConApp_maybe We hvae been making exprIsConApp_maybe cleverer in recent times: commit b78cc64e923716ac0512c299f42d4d0012306c05 Date: Thu Nov 15 17:14:31 2018 +0100 Make constructor wrappers inline only during the final phase commit 7833cf407d1f608bebb1d38bb99d3035d8d735e6 Date: Thu Jan 24 17:58:50 2019 +0100 Look through newtype wrappers (Trac #16254) commit c25b135ff5b9c69a90df0ccf51b04952c2dc6ee1 Date: Thu Feb 21 12:03:22 2019 +0000 Fix exprIsConApp_maybe But alas there was still a bug, now immortalised in Note [Don't float join points] in SimpleOpt. It's quite hard to trigger because it requires a dead join point, but it came up when compiling Cabal Cabal.Distribution.Fields.Lexer.hs, when working on !3113. Happily, the fix is extremly easy. Finding the bug was not so easy. - - - - - 0f01db64 by Ben Gamari at 2020-04-24T15:13:59-04:00 codeGen: A bit of debugging output - - - - - ede8dd24 by Ben Gamari at 2020-04-24T15:42:56-04:00 Allow simplification through runRW# TODO. Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Session.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5d42156a0581bf7696a6ffd7c2cc250247d48a0...ede8dd245ba9ee89db052260c307e784e8eab474 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5d42156a0581bf7696a6ffd7c2cc250247d48a0...ede8dd245ba9ee89db052260c307e784e8eab474 You're receiving 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 24 20:16:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 16:16:46 -0400 Subject: [Git][ghc/ghc][wip/runRW] 4 commits: CoreToStg: Add Outputable ArgInfo instance Message-ID: <5ea3492e67c50_6167e5b4fc46987056@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: 306dba47 by Ben Gamari at 2020-04-24T16:16:37-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - b9eebc84 by Simon Peyton Jones at 2020-04-24T16:16:37-04:00 Make Lint check return type of a join point Consider join x = rhs in body It's important that the type of 'rhs' is the same as the type of 'body', but Lint wasn't checking that invariant. Now it does! This was exposed by investigation into !3113. - - - - - 891fc8b2 by Simon Peyton Jones at 2020-04-24T16:16:37-04:00 Do not float join points in exprIsConApp_maybe We hvae been making exprIsConApp_maybe cleverer in recent times: commit b78cc64e923716ac0512c299f42d4d0012306c05 Date: Thu Nov 15 17:14:31 2018 +0100 Make constructor wrappers inline only during the final phase commit 7833cf407d1f608bebb1d38bb99d3035d8d735e6 Date: Thu Jan 24 17:58:50 2019 +0100 Look through newtype wrappers (Trac #16254) commit c25b135ff5b9c69a90df0ccf51b04952c2dc6ee1 Date: Thu Feb 21 12:03:22 2019 +0000 Fix exprIsConApp_maybe But alas there was still a bug, now immortalised in Note [Don't float join points] in SimpleOpt. It's quite hard to trigger because it requires a dead join point, but it came up when compiling Cabal Cabal.Distribution.Fields.Lexer.hs, when working on !3113. Happily, the fix is extremly easy. Finding the bug was not so easy. - - - - - 8d548e83 by Ben Gamari at 2020-04-24T16:16:37-04:00 Allow simplification through runRW# Because runRW# inlines so late, we were previously able to do very little simplification across it. For instance, given even a simple program like case runRW# (\s -> let n = I# 42# in n) of I# n# -> f n# we previously had no way to avoid the allocation of the I#. This patch allows the simplifier to push strict contexts into the continuation of a runRW# application, as explained in in Note [Simplification of runRW#] in GHC.CoreToStg.Prep. Fixes #15127. Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 7 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Utils.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -461,7 +461,7 @@ lintCoreBindings dflags pass local_in_scope binds addLoc TopLevelBindings $ do { checkL (null dups) (dupVars dups) ; checkL (null ext_dups) (dupExtVars ext_dups) - ; lintRecBindings TopLevel all_pairs $ + ; lintRecBindings TopLevel all_pairs $ \_ -> return () } where all_pairs = flattenBinds binds @@ -572,11 +572,11 @@ Check a core binding, returning the list of variables bound. -} lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)] - -> LintM a -> LintM a + -> ([LintedId] -> LintM a) -> LintM a lintRecBindings top_lvl pairs thing_inside = lintIdBndrs top_lvl bndrs $ \ bndrs' -> do { zipWithM_ lint_pair bndrs' rhss - ; thing_inside } + ; thing_inside bndrs' } where (bndrs, rhss) = unzip pairs lint_pair bndr' rhs @@ -584,6 +584,12 @@ lintRecBindings top_lvl pairs thing_inside do { rhs_ty <- lintRhs bndr' rhs -- Check the rhs ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty } +lintLetBody :: [LintedId] -> CoreExpr -> LintM LintedType +lintLetBody bndrs body + = do { body_ty <- addLoc (BodyOfLetRec bndrs) (lintCoreExpr body) + ; mapM_ (lintJoinBndrType body_ty) bndrs + ; return body_ty } + lintLetBind :: TopLevelFlag -> RecFlag -> LintedId -> CoreExpr -> LintedType -> LintM () -- Binder's type, and the RHS, have already been linted @@ -678,22 +684,9 @@ lintRhs :: Id -> CoreExpr -> LintM LintedType -- its OccInfo and join-pointer-hood lintRhs bndr rhs | Just arity <- isJoinId_maybe bndr - = lint_join_lams arity arity True rhs + = lintJoinLams arity (Just bndr) rhs | AlwaysTailCalled arity <- tailCallInfo (idOccInfo bndr) - = lint_join_lams arity arity False rhs - where - lint_join_lams 0 _ _ rhs - = lintCoreExpr rhs - - lint_join_lams n tot enforce (Lam var expr) - = lintLambda var $ lint_join_lams (n-1) tot enforce expr - - lint_join_lams n tot True _other - = failWithL $ mkBadJoinArityMsg bndr tot (tot-n) rhs - lint_join_lams _ _ False rhs - = markAllJoinsBad $ lintCoreExpr rhs - -- Future join point, not yet eta-expanded - -- Body is not a tail position + = lintJoinLams arity Nothing rhs -- Allow applications of the data constructor @StaticPtr@ at the top -- but produce errors otherwise. @@ -715,6 +708,22 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go binders0 go _ = markAllJoinsBad $ lintCoreExpr rhs +-- | Lint the RHS of a join point with expected join arity of @n@ (see Note +-- [Join points] in GHC.Core). +lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM LintedType +lintJoinLams join_arity enforce rhs + = go join_arity rhs + where + go 0 rhs = lintCoreExpr rhs + go n (Lam var expr) = lintLambda var $ go (n-1) expr + -- N.B. join points can be cast. e.g. we consider ((\x -> ...) `cast` ...) + -- to be a join point at join arity 1. + go n _other | Just bndr <- enforce -- Join point with too few RHS lambdas + = failWithL $ mkBadJoinArityMsg bndr join_arity n rhs + | otherwise -- Future join point, not yet eta-expanded + = markAllJoinsBad $ lintCoreExpr rhs + -- Body of lambda is not a tail position + lintIdUnfolding :: Id -> Type -> Unfolding -> LintM () lintIdUnfolding bndr bndr_ty uf | isStableUnfolding uf @@ -755,6 +764,40 @@ we will check any unfolding after it has been unfolded; checking the unfolding beforehand is merely an optimization, and one that actively hurts us here. +Note [Linting of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~ +runRW# has some very peculiar behavior (see Note [runRW magic] in +GHC.CoreToStg.Prep) which CoreLint must accommodate. + +As described in Note [Casts and lambdas] in +GHC.Core.Opt.Simplify.Utils, the simplifier pushes casts out of +lambdas. Concretely, the simplifier will transform + + runRW# @r @ty (\s -> expr `cast` co) + +into + + runRW# @r @ty ((\s -> expr) `cast` co) + +Consequently we need to handle the case that the continuation is a +cast of a lambda. See Note [Casts and lambdas] in +GHC.Core.Opt.Simplify.Utils. + +In the event that the continuation is headed by a lambda (which +will bind the State# token) we can safely allow calls to join +points since CorePrep is going to apply the continuation to +RealWorld. + +In the case that the continuation is not a lambda we lint the +continuation disallowing join points, to rule out things like, + + join j = ... + in runRW# @r @ty ( + let x = jump j + in x + ) + + ************************************************************************ * * \subsection[lintCoreExpr]{lintCoreExpr} @@ -769,6 +812,18 @@ type LintedCoercion = Coercion type LintedTyCoVar = TyCoVar type LintedId = Id +-- | Lint an expression cast through the given coercion, returning the type +-- resulting from the cast. +lintCastExpr :: CoreExpr -> LintedType -> Coercion -> LintM LintedType +lintCastExpr expr expr_ty co + = do { co' <- lintCoercion co + ; let (Pair from_ty to_ty, role) = coercionKindRole co' + ; checkValueType to_ty $ + text "target of cast" <+> quotes (ppr co') + ; lintRole co' Representational role + ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) + ; return to_ty } + lintCoreExpr :: CoreExpr -> LintM LintedType -- The returned type has the substitution from the monad -- already applied to it: @@ -786,14 +841,8 @@ lintCoreExpr (Lit lit) = return (literalType lit) lintCoreExpr (Cast expr co) - = do { expr_ty <- markAllJoinsBad $ lintCoreExpr expr - ; co' <- lintCoercion co - ; let (Pair from_ty to_ty, role) = coercionKindRole co' - ; checkValueType to_ty $ - text "target of cast" <+> quotes (ppr co') - ; lintRole co' Representational role - ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) - ; return to_ty } + = do expr_ty <- markAllJoinsBad $ lintCoreExpr expr + lintCastExpr expr expr_ty co lintCoreExpr (Tick tickish expr) = do case tickish of @@ -830,7 +879,7 @@ lintCoreExpr (Let (NonRec bndr rhs) body) -- Now lint the binder ; lintBinder LetBind bndr $ \bndr' -> do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty - ; addLoc (BodyOfLetRec [bndr]) (lintCoreExpr body) } } + ; lintLetBody [bndr'] body } } | otherwise = failWithL (mkLetErr bndr rhs) -- Not quite accurate @@ -847,13 +896,37 @@ lintCoreExpr e@(Let (Rec pairs) body) ; checkL (all isJoinId bndrs || all (not . isJoinId) bndrs) $ mkInconsistentRecMsg bndrs - ; lintRecBindings NotTopLevel pairs $ - addLoc (BodyOfLetRec bndrs) $ - lintCoreExpr body } + ; lintRecBindings NotTopLevel pairs $ \ bndrs' -> + lintLetBody bndrs' body } where bndrs = map fst pairs lintCoreExpr e@(App _ _) + | Var fun <- fun + , fun `hasKey` runRWKey + -- N.B. we may have an over-saturated application of the form: + -- runRW (\s -> \x -> ...) y + , arg_ty1 : arg_ty2 : arg3 : rest <- args + = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 + ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 + -- See Note [Linting of runRW#] + ; let lintRunRWCont :: CoreArg -> LintM LintedType + lintRunRWCont (Cast expr co) = do + ty <- lintRunRWCont expr + lintCastExpr expr ty co + lintRunRWCont expr@(Lam _ _) = do + lintJoinLams 1 (Just fun) expr + lintRunRWCont other = markAllJoinsBad $ lintCoreExpr other + -- TODO: Look through ticks? + ; arg3_ty <- lintRunRWCont arg3 + ; app_ty <- lintValApp arg3 fun_ty2 arg3_ty + ; lintCoreArgs app_ty rest } + + | Var fun <- fun + , fun `hasKey` runRWKey + = failWithL (text "Invalid runRW# application") + + | otherwise = do { fun_ty <- lintCoreFun fun (length args) ; lintCoreArgs fun_ty args } where @@ -950,6 +1023,25 @@ checkDeadIdOcc id = return () ------------------ +lintJoinBndrType :: LintedType -- Type of the body + -> LintedId -- Possibly a join Id + -> LintM () +-- Checks that the return type of a join Id matches the body +-- E.g. join j x = rhs in body +-- The type of 'rhs' must be the same as the type of 'body' +lintJoinBndrType body_ty bndr + | Just arity <- isJoinId_maybe bndr + , let bndr_ty = idType bndr + , (bndrs, res) <- splitPiTys bndr_ty + = checkL (length bndrs >= arity + && body_ty `eqType` mkPiTys (drop arity bndrs) res) $ + hang (text "Join point returns different type than body") + 2 (vcat [ text "Join bndr:" <+> ppr bndr <+> dcolon <+> ppr (idType bndr) + , text "Join arity:" <+> ppr arity + , text "Body type:" <+> ppr body_ty ]) + | otherwise + = return () + checkJoinOcc :: Id -> JoinArity -> LintM () -- Check that if the occurrence is a JoinId, then so is the -- binding site, and it's a valid join Id @@ -1114,11 +1206,15 @@ lintTyApp fun_ty arg_ty = failWithL (mkTyAppMsg fun_ty arg_ty) ----------------- + +-- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@ +-- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the +-- application. lintValApp :: CoreExpr -> LintedType -> LintedType -> LintM LintedType lintValApp arg fun_ty arg_ty - | Just (arg,res) <- splitFunTy_maybe fun_ty - = do { ensureEqTys arg arg_ty err1 - ; return res } + | Just (arg_ty', res_ty') <- splitFunTy_maybe fun_ty + = do { ensureEqTys arg_ty' arg_ty err1 + ; return res_ty' } | otherwise = failWithL err2 where @@ -2751,11 +2847,11 @@ mkInvalidJoinPointMsg var ty 2 (ppr var <+> dcolon <+> ppr ty) mkBadJoinArityMsg :: Var -> Int -> Int -> CoreExpr -> SDoc -mkBadJoinArityMsg var ar nlams rhs +mkBadJoinArityMsg var ar n rhs = vcat [ text "Join point has too few lambdas", text "Join var:" <+> ppr var, text "Join arity:" <+> ppr ar, - text "Number of lambdas:" <+> ppr nlams, + text "Number of lambdas:" <+> ppr (ar - n), text "Rhs = " <+> ppr rhs ] ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -39,6 +39,7 @@ import GHC.Types.Demand ( argOneShots, argsOneShots ) import Digraph ( SCC(..), Node(..) , stronglyConnCompFromEdgedVerticesUniq , stronglyConnCompFromEdgedVerticesUniqR ) +import GHC.Builtin.Names( runRWKey ) import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set @@ -1882,8 +1883,15 @@ occAnalApp :: OccEnv -> (UsageDetails, Expr CoreBndr) -- Naked variables (not applied) end up here too occAnalApp env (Var fun, args, ticks) - | null ticks = (all_uds, mkApps fun' args') - | otherwise = (all_uds, mkTicks ticks $ mkApps fun' args') + -- Account for join arity of runRW# continuation + -- See Note [Simplification of runRW#] + | fun `hasKey` runRWKey + , [t1, t2, arg] <- args + , let (usage, arg') = occAnalRhs env (Just 1) arg + = (usage, mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']) + + | otherwise + = (all_uds, mkTicks ticks $ mkApps fun' args') where (fun', fun_id') = lookupVarEnv (occ_bs_env env) fun `orElse` (Var fun, fun) ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -1,7 +1,7 @@ {- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -\section{GHC.Core.Opt.SetLevels} +\section{GHC.Core.Op.SetLevels} *************************** Overview @@ -91,12 +91,14 @@ import GHC.Types.Demand ( StrictSig, Demand, isStrictDmd, splitStrictSig, import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Types.Name ( getOccName, mkSystemVarName ) import GHC.Types.Name.Occurrence ( occNameString ) +import GHC.Types.Unique ( hasKey ) import GHC.Core.Type ( Type, mkLamTypes, splitTyConApp_maybe, tyCoVarsOfType , mightBeUnliftedType, closeOverKindsDSet ) import GHC.Types.Basic ( Arity, RecFlag(..), isRec ) import GHC.Core.DataCon ( dataConOrigResTy ) import GHC.Builtin.Types import GHC.Types.Unique.Supply +import GHC.Builtin.Names ( runRWKey ) import Util import Outputable import FastString @@ -399,8 +401,14 @@ lvlNonTailExpr env expr lvlApp :: LevelEnv -> CoreExprWithFVs -> (CoreExprWithFVs, [CoreExprWithFVs]) -- Input application - -> LvlM LevelledExpr -- Result expression + -> LvlM LevelledExpr -- Result expression lvlApp env orig_expr ((_,AnnVar fn), args) + -- Try to ensure that runRW#'s continuation isn't floated out. + -- See Note [Simplification of runRW#]. + | fn `hasKey` runRWKey + = do { args' <- mapM (lvlExpr env) args + ; return (foldl' App (lookupVar env fn) args') } + | floatOverSat env -- See Note [Floating over-saturated applications] , arity > 0 , arity < n_val_args ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -37,10 +37,13 @@ import GHC.Core.DataCon , StrictnessMark (..) ) import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) ) import GHC.Core +import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) +import GHC.Builtin.Names( runRWKey ) import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Core.Ppr ( pprCoreExpr ) +import GHC.Types.Unique ( hasKey ) import GHC.Core.Unfold import GHC.Core.Utils import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg @@ -1877,14 +1880,36 @@ rebuildCall env info (CastIt co cont) rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) = rebuildCall env (addTyArgTo info arg_ty) cont -rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty +---------- The runRW# rule. Do this after absorbing all arguments ------ +-- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o +-- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) + (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) + | fun `hasKey` runRWKey + , not (contIsStop cont) -- Don't fiddle around if the continuation is boring + , [ TyArg {}, TyArg {} ] <- rev_args + = do { s <- newId (fsLit "s") realWorldStatePrimTy + ; let env' = (arg_se `setInScopeFromE` env) `addNewInScopeIds` [s] + cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s + , sc_env = env', sc_cont = cont } + ; body' <- simplExprC env' arg cont' + ; let arg' = Lam s body' + ty' = contResultType cont + rr' = getRuntimeRep ty' + call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] + ; return (emptyFloats env, call') } + +rebuildCall env info@(ArgInfo { ai_type = fun_ty, ai_encl = encl_rules , ai_strs = str:strs, ai_discs = disc:discs }) (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_cont = cont }) + + -- Argument is already simplified | isSimplified dup_flag -- See Note [Avoid redundant simplification] = rebuildCall env (addValArgTo info' arg) cont - | str -- Strict argument + -- Strict arguments + | str , sm_case_case (getMode env) = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $ simplExprF (arg_se `setInScopeFromE` env) arg @@ -1892,7 +1917,8 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty , sc_dup = Simplified, sc_cont = cont }) -- Note [Shadowing] - | otherwise -- Lazy argument + -- Lazy arguments + | otherwise -- DO NOT float anything outside, hence simplExprC -- There is no benefit (unlike in a let-binding), and we'd -- have to be very careful about bogus strictness through ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -954,6 +954,31 @@ will happen the next time either. See test T16254, which checks the behavior of newtypes. +Note [Don't float join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +exprIsConApp_maybe should succeed on + let v = e in Just v +returning [x=e] as one of the [FloatBind]. But it must +NOT succeed on + join j x = rhs in Just v +because join-points can't be gaily floated. Consider + case (join j x = rhs in Just) of + K p q -> blah +We absolutely must not "simplify" this to + join j x = rhs + in blah +because j's return type is (Maybe t), quite different to blah's. + +You might think this could never happen, because j can't be +tail-called in the body if the body returns a constructor. But +in !3113 we had a /dead/ join point (which is not illegal), +and its return type was wonky. + +The simple thing is not to float a join point. The next iteration +of the simplifier will sort everything out. And it there is +a join point, the chances are that the body is not a constructor +application, so failing faster is good. + Note [exprIsConApp_maybe for data-con wrappers: tricky corner] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Generally speaking @@ -1062,6 +1087,8 @@ exprIsConApp_maybe (in_scope, id_unf) expr in go subst' (float:floats) body (CC args co) go subst floats (Let (NonRec bndr rhs) expr) cont + | not (isJoinId bndr) + -- Crucial guard! See Note [Don't float join points] = let rhs' = subst_expr subst rhs (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' rhs') ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -760,7 +760,13 @@ data ArgInfo = CpeApp CoreArg | CpeCast Coercion | CpeTick (Tickish Id) -{- Note [runRW arg] +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 + +{- + Note [runRW arg] ~~~~~~~~~~~~~~~~~~~ If we got, say runRW# (case bot of {}) @@ -823,14 +829,23 @@ cpeApp top_env expr -- rather than the far superior "f x y". Test case is par01. = let (terminal, args', depth') = collect_args arg in cpe_app env terminal (args' ++ args) (depth + depth' - 1) - cpe_app env (Var f) [CpeApp _runtimeRep at Type{}, CpeApp _type at Type{}, CpeApp arg] 1 + cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) n | 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 + , n >= 1 -- 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 [] 0 - _ -> cpe_app env arg [CpeApp (Var realWorldPrimId)] 1 + Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest (n-2) + _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) (n-1) + -- TODO: What about casts? + + cpe_app _env (Var f) args n + | f `hasKey` runRWKey + = pprPanic "cpe_app(runRW#)" (ppr args $$ ppr n) + cpe_app env (Var v) args depth = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -959,8 +974,77 @@ pragma. It is levity-polymorphic. => (State# RealWorld -> (# State# RealWorld, o #)) -> (# State# RealWorld, o #) -It needs no special treatment in GHC except this special inlining here -in CorePrep (and in GHC.CoreToByteCode). +It's correctness needs no special treatment in GHC except this special inlining +here in CorePrep (and in GHC.CoreToByteCode). + +However, there are a variety of optimisation opportunities that the simplifier +takes advantage of. See Note [Simplification of runRW#]. + + +Note [Simplification of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the program, + + case runRW# (\s -> let n = I# 42# in n) of + I# n# -> f n# + +There is no reason why we should allocate an I# constructor given that we +immediately destructure it. To avoid this the simplifier will push strict +contexts into runRW's continuation. That is, it transforms + + K[ runRW# @r @ty cont ] + ~> + runRW# @r @ty K[cont] + +This has a few interesting implications. Consider, for instance, this program: + + join j = ... + in case runRW# @r @ty cont of + result -> jump j result + +Performing the transform described above would result in: + + join j x = ... + in runRW# @r @ty (\s -> + case cont of in + result -> jump j result + ) + +If runRW# were a "normal" function this call to join point j would not be +allowed in its continuation argument. However, since runRW# is inlined (as +described in Note [runRW magic] above), such join point occurences are +completely fine. Both occurrence analysis and Core Lint have special treatment +for runRW# applications. See Note [Linting of runRW#] for details on the latter. + +Moreover, it's helpful to ensure that runRW's continuation isn't floated out +(since doing so would then require a call, whereas we would otherwise end up +with straight-line). Consequently, GHC.Core.Opt.SetLevels.lvlApp has special +treatment for runRW# applications, ensure the arguments are not floated if +MFEs. + +Other considered designs +------------------------ + +One design that was rejected was to *require* that runRW#'s continuation be +headed by a lambda. However, this proved to be quite fragile. For instance, +SetLevels is very eager to float bottoming expressions. For instance given +something of the form, + + runRW# @r @ty (\s -> case expr of x -> undefined) + +SetLevels will see that the body the lambda is bottoming and will consequently +float it to the top-level (assuming expr has no free coercion variables which +prevent this). We therefore end up with + + runRW# @r @ty (\s -> lvl s) + +Which the simplifier will beta reduce, leaving us with + + runRW# @r @ty lvl + +Breaking our desired invariant. Ultimately we decided to simply accept that +the continuation may not be a manifest lambda. + -- --------------------------------------------------------------------------- -- CpeArg: produces a result satisfying CpeArg ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -482,7 +482,6 @@ mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg Var v1 | isInternalName (idName v1) -> v1 -- Note [Desugaring seq], points (2) and (3) _ -> mkWildValBinder ty1 - mkCoreAppDs s fun arg = mkCoreApp s fun arg -- The rest is done in GHC.Core.Make -- NB: No argument can be levity polymorphic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ede8dd245ba9ee89db052260c307e784e8eab474...8d548e8304ea7d8f3955681597be0c655ab6fb2d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ede8dd245ba9ee89db052260c307e784e8eab474...8d548e8304ea7d8f3955681597be0c655ab6fb2d You're receiving 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 24 21:23:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 17:23:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18079 Message-ID: <5ea358b99cbdb_61673f813dcf07f869883c@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18079 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18079 You're receiving 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 24 22:24:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 18:24:23 -0400 Subject: [Git][ghc/ghc][wip/T18079] Eta expand un-saturated primops Message-ID: <5ea367177fe36_61673f81afeb5fbc69948c5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18079 at Glasgow Haskell Compiler / GHC Commits: 10ca4f42 by Ben Gamari at 2020-04-24T18:24:15-04:00 Eta expand un-saturated primops - - - - - 7 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id.hs - testsuite/tests/codeGen/should_fail/T13233.hs - testsuite/tests/codeGen/should_fail/T13233.stderr Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -590,33 +590,83 @@ primOpOcc op = case primOpInfo op of {- Note [Primop wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Previously hasNoBinding would claim that PrimOpIds didn't have a curried -function definition. This caused quite some trouble as we would be forced to -eta expand unsaturated primop applications very late in the Core pipeline. Not -only would this produce unnecessary thunks, but it would also result in nasty -inconsistencies in CAFfy-ness determinations (see #16846 and -Note [CAFfyness inconsistencies due to late eta expansion] in GHC.Iface.Tidy). - -However, it was quite unnecessary for hasNoBinding to claim this; primops in -fact *do* have curried definitions which are found in GHC.PrimopWrappers, which -is auto-generated by utils/genprimops from prelude/primops.txt.pp. These wrappers -are standard Haskell functions mirroring the types of the primops they wrap. -For instance, in the case of plusInt# we would have: + +To support (limited) use of primops in GHCi genprimopcode generates the +GHC.PrimopWrappers module. This module contains a "primop wrapper" +binding for each primop. These are standard Haskell functions mirroring the +types of the primops they wrap. For instance, in the case of plusInt# we would +have: module GHC.PrimopWrappers where import GHC.Prim as P + + plusInt# :: Int# -> Int# -> Int# plusInt# a b = P.plusInt# a b -We now take advantage of these curried definitions by letting hasNoBinding -claim that PrimOpIds have a curried definition and then rewrite any unsaturated -PrimOpId applications that we find during CoreToStg as applications of the -associated wrapper (e.g. `GHC.Prim.plusInt# 3#` will get rewritten to -`GHC.PrimopWrappers.plusInt# 3#`).` The Id of the wrapper for a primop can be -found using 'PrimOp.primOpWrapperId'. +The Id for the wrapper of a primop can be found using +'GHC.Builtin.PrimOp.primOpWrapperId'. However, GHCi does not use this mechanism +to link primops; it rather does a rather hacky symbol lookup (see +GHC.ByteCode.Linker.primopToCLabel). TODO: Perhaps this should be changed? + +Note that these wrappers aren't *quite* +as expressive as their unwrapped breathern in that they may exhibit less levity +polymorphism. For instance, consider the case of mkWeakNoFinalizer# which has +type: + + mkWeakNoFinalizer# :: forall (r :: RuntimeRep) (k :: TYPE r) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +Naively we could generate a wrapper of the form, + + + mkWeakNoFinalizer# k v s = GHC.Prim.mkWeakNoFinalizer# k v s + +However, this would require that 'k' bind the levity-polymorphic key, +which is disallowed by our levity polymorphism validity checks (see Note +[Levity polymorphism invariants] in GHC.Core). Consequently, we give the +wrapper the simpler, less polymorphic type + + mkWeakNoFinalizer# :: forall (k :: Type) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +This simplification tends to be good enough for GHCi uses given that there are +few levity polymorphic primops and we do little simplification on interpreted +code anyways. + +TODO: This behavior is actually wrong; a program becomes ill-typed upon +replacing a real primop occurrence with one of its wrapper due to the fact that +the former has an additional type binder. Hmmm.... + +Note [Eta expanding primops] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +STG requires that primop applications be saturated. This makes code generation +significantly simpler since otherwise we would need to define a calling +convention for curried applications that can accomodate levity polymorphism. + +To ensure saturation, CorePrep eta expands expand all primop applications as +described in Note [Eta expansion of hasNoBinding things in CorePrep] in +GHC.Core.Prep. + +Historical Note: -Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's -used by GHCi, which does not implement primops direct at all. +For a short period around GHC 8.8 we rewrote unsaturated primop applications to +rather use the primop's wrapper (see Note [Primop wrappers] in +GHC.Builtin.PrimOps) instead of eta expansion. This was because at the time +CoreTidy would try to predict the CAFfyness of bindings that would be produced +by CorePrep for inclusion in interface files. Eta expanding during CorePrep +proved to be very difficult to predict, leading to nasty inconsistencies in +CAFfyness determinations (see #16846). +Thankfully, we now no longer try to predict CAFfyness but rather compute it on +GHC STG (see Note [SRTs] in GHC.Cmm.Info.Build) and inject it into the interface +file after code generation (see TODO: Refer to whatever falls out of #18096). +This is much simpler and avoids the potential for inconsistency, allowing us to +return to the somewhat simpler eta expansion approach for unsaturated primops. -} -- | Returns the 'Id' of the wrapper associated with the given 'PrimOp'. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -176,6 +176,7 @@ nameToCLabel n suffix = mkFastString label ] +-- See Note [Primop wrappers] in GHC.Builtin.PrimOps primopToCLabel :: PrimOp -> String -> String primopToCLabel primop suffix = concat [ "ghczmprim_GHCziPrimopWrappers_" ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -539,12 +539,10 @@ coreToStgApp f args ticks = do (dropRuntimeRepArgs (fromMaybe [] (tyConAppArgs_maybe res_ty))) -- Some primitive operator that might be implemented as a library call. - -- As described in Note [Primop wrappers] in GHC.Builtin.PrimOps, here we - -- turn unsaturated primop applications into applications of - -- the primop's wrapper. - PrimOpId op - | saturated -> StgOpApp (StgPrimOp op) args' res_ty - | otherwise -> StgApp (primOpWrapperId op) args' + -- As noted by Note [Eta expanding primops] in GHC.Builtin.PrimOps + -- we require that primop applications be saturated. + PrimOpId op -> ASSERT( saturated ) + StgOpApp (StgPrimOp op) args' res_ty -- A call to some primitive Cmm function. FCallId (CCall (CCallSpec (StaticTarget _ lbl (Just pkgId) True) ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -71,7 +71,7 @@ import qualified Data.Set as S The goal of this pass is to prepare for code generation. -1. Saturate constructor applications. +1. Saturate constructor and primop applications. 2. Convert to A-normal form; that is, function arguments are always variables. @@ -1067,15 +1067,11 @@ maybeSaturate deals with eta expanding to saturate things that can't deal with unsaturated applications (identified by 'hasNoBinding', currently just foreign calls and unboxed tuple/sum constructors). -Note that eta expansion in CorePrep is very fragile due to the "prediction" of -CAFfyness made during tidying (see Note [CAFfyness inconsistencies due to eta -expansion in CorePrep] in GHC.Iface.Tidy for details. We previously saturated primop +Historical Note: Note that eta expansion in CorePrep used to be very fragile +due to the "prediction" of CAFfyness that we used to make during tidying. +We previously saturated primop applications here as well but due to this fragility (see #16846) we now deal with this another way, as described in Note [Primop wrappers] in GHC.Builtin.PrimOps. - -It's quite likely that eta expansion of constructor applications will -eventually break in a similar way to how primops did. We really should -eliminate this case as well. -} maybeSaturate :: Id -> CpeApp -> Int -> UniqSM CpeRhs ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -515,20 +515,12 @@ hasNoBinding :: Id -> Bool -- ^ Returns @True@ of an 'Id' which may not have a -- binding, even though it is defined in this module. --- Data constructor workers used to be things of this kind, but --- they aren't any more. Instead, we inject a binding for --- them at the CorePrep stage. --- --- 'PrimOpId's also used to be of this kind. See Note [Primop wrappers] in GHC.Builtin.PrimOps. --- for the history of this. --- --- Note that CorePrep currently eta expands things no-binding things and this --- can cause quite subtle bugs. See Note [Eta expansion of hasNoBinding things --- in CorePrep] in CorePrep for details. --- --- EXCEPT: unboxed tuples, which definitely have no binding +-- Data constructor workers used to be things of this kind, but they aren't any +-- more. Instead, we inject a binding for them at the CorePrep stage. The +-- exception to this is unboxed tuples and sums datacons, which definitely have +-- no binding hasNoBinding id = case Var.idDetails id of - PrimOpId _ -> False -- See Note [Primop wrappers] in GHC.Builtin.PrimOps + PrimOpId _ -> True -- See Note [Eta expanding primops] in GHC.Builtin.PrimOps FCallId _ -> True DataConWorkId dc -> isUnboxedTupleCon dc || isUnboxedSumCon dc _ -> isCompulsoryUnfolding (idUnfolding id) ===================================== testsuite/tests/codeGen/should_fail/T13233.hs ===================================== @@ -21,9 +21,6 @@ obscure _ = () quux :: () quux = obscure (#,#) --- It used to be that primops has no binding. However, as described in --- Note [Primop wrappers] in GHC.Builtin.PrimOps we now rewrite unsaturated primop --- applications to their wrapper, which allows safe use of levity polymorphism. primop :: forall (rep :: RuntimeRep) (a :: TYPE rep) b c. a -> b -> (State# RealWorld -> (# State# RealWorld, c #)) -> State# RealWorld -> (# State# RealWorld, Weak# b #) ===================================== testsuite/tests/codeGen/should_fail/T13233.stderr ===================================== @@ -20,3 +20,11 @@ T13233.hs:22:16: error: Levity-polymorphic arguments: a :: TYPE rep1 b :: TYPE rep2 + +T13233.hs:27:10: error: + Cannot use function with levity-polymorphic arguments: + mkWeak# :: a + -> b + -> (State# RealWorld -> (# State# RealWorld, c #)) + -> State# RealWorld + -> (# State# RealWorld, Weak# b #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/10ca4f42c85eab87fd97e9f1557ce5538f42ed51 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/10ca4f42c85eab87fd97e9f1557ce5538f42ed51 You're receiving 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 24 22:27:37 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 18:27:37 -0400 Subject: [Git][ghc/ghc][wip/T18079] Eta expand un-saturated primops Message-ID: <5ea367d9c68c7_61673f81cc8e1c046995288@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18079 at Glasgow Haskell Compiler / GHC Commits: de4c785c by Ben Gamari at 2020-04-24T18:27:29-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - 7 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id.hs - testsuite/tests/codeGen/should_fail/T13233.hs - testsuite/tests/codeGen/should_fail/T13233.stderr Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -590,33 +590,85 @@ primOpOcc op = case primOpInfo op of {- Note [Primop wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Previously hasNoBinding would claim that PrimOpIds didn't have a curried -function definition. This caused quite some trouble as we would be forced to -eta expand unsaturated primop applications very late in the Core pipeline. Not -only would this produce unnecessary thunks, but it would also result in nasty -inconsistencies in CAFfy-ness determinations (see #16846 and -Note [CAFfyness inconsistencies due to late eta expansion] in GHC.Iface.Tidy). - -However, it was quite unnecessary for hasNoBinding to claim this; primops in -fact *do* have curried definitions which are found in GHC.PrimopWrappers, which -is auto-generated by utils/genprimops from prelude/primops.txt.pp. These wrappers -are standard Haskell functions mirroring the types of the primops they wrap. -For instance, in the case of plusInt# we would have: + +To support (limited) use of primops in GHCi genprimopcode generates the +GHC.PrimopWrappers module. This module contains a "primop wrapper" +binding for each primop. These are standard Haskell functions mirroring the +types of the primops they wrap. For instance, in the case of plusInt# we would +have: module GHC.PrimopWrappers where import GHC.Prim as P + + plusInt# :: Int# -> Int# -> Int# plusInt# a b = P.plusInt# a b -We now take advantage of these curried definitions by letting hasNoBinding -claim that PrimOpIds have a curried definition and then rewrite any unsaturated -PrimOpId applications that we find during CoreToStg as applications of the -associated wrapper (e.g. `GHC.Prim.plusInt# 3#` will get rewritten to -`GHC.PrimopWrappers.plusInt# 3#`).` The Id of the wrapper for a primop can be -found using 'PrimOp.primOpWrapperId'. +The Id for the wrapper of a primop can be found using +'GHC.Builtin.PrimOp.primOpWrapperId'. However, GHCi does not use this mechanism +to link primops; it rather does a rather hacky symbol lookup (see +GHC.ByteCode.Linker.primopToCLabel). TODO: Perhaps this should be changed? + +Note that these wrappers aren't *quite* +as expressive as their unwrapped breathern in that they may exhibit less levity +polymorphism. For instance, consider the case of mkWeakNoFinalizer# which has +type: + + mkWeakNoFinalizer# :: forall (r :: RuntimeRep) (k :: TYPE r) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +Naively we could generate a wrapper of the form, + + + mkWeakNoFinalizer# k v s = GHC.Prim.mkWeakNoFinalizer# k v s + +However, this would require that 'k' bind the levity-polymorphic key, +which is disallowed by our levity polymorphism validity checks (see Note +[Levity polymorphism invariants] in GHC.Core). Consequently, we give the +wrapper the simpler, less polymorphic type + + mkWeakNoFinalizer# :: forall (k :: Type) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +This simplification tends to be good enough for GHCi uses given that there are +few levity polymorphic primops and we do little simplification on interpreted +code anyways. + +TODO: This behavior is actually wrong; a program becomes ill-typed upon +replacing a real primop occurrence with one of its wrapper due to the fact that +the former has an additional type binder. Hmmm.... + +Note [Eta expanding primops] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +STG requires that primop applications be saturated. This makes code generation +significantly simpler since otherwise we would need to define a calling +convention for curried applications that can accomodate levity polymorphism. + +To ensure saturation, CorePrep eta expands expand all primop applications as +described in Note [Eta expansion of hasNoBinding things in CorePrep] in +GHC.Core.Prep. + +Historical Note: + +For a short period around GHC 8.8 we rewrote unsaturated primop applications to +rather use the primop's wrapper (see Note [Primop wrappers] in +GHC.Builtin.PrimOps) instead of eta expansion. This was because at the time +CoreTidy would try to predict the CAFfyness of bindings that would be produced +by CorePrep for inclusion in interface files. Eta expanding during CorePrep +proved to be very difficult to predict, leading to nasty inconsistencies in +CAFfyness determinations (see #16846). -Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's -used by GHCi, which does not implement primops direct at all. +Thankfully, we now no longer try to predict CAFfyness but rather compute it on +GHC STG (see Note [SRTs] in GHC.Cmm.Info.Build) and inject it into the interface +file after code generation (see TODO: Refer to whatever falls out of #18096). +This is much simpler and avoids the potential for inconsistency, allowing us to +return to the somewhat simpler eta expansion approach for unsaturated primops. +See #18079. -} -- | Returns the 'Id' of the wrapper associated with the given 'PrimOp'. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -176,6 +176,7 @@ nameToCLabel n suffix = mkFastString label ] +-- See Note [Primop wrappers] in GHC.Builtin.PrimOps primopToCLabel :: PrimOp -> String -> String primopToCLabel primop suffix = concat [ "ghczmprim_GHCziPrimopWrappers_" ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -539,12 +539,10 @@ coreToStgApp f args ticks = do (dropRuntimeRepArgs (fromMaybe [] (tyConAppArgs_maybe res_ty))) -- Some primitive operator that might be implemented as a library call. - -- As described in Note [Primop wrappers] in GHC.Builtin.PrimOps, here we - -- turn unsaturated primop applications into applications of - -- the primop's wrapper. - PrimOpId op - | saturated -> StgOpApp (StgPrimOp op) args' res_ty - | otherwise -> StgApp (primOpWrapperId op) args' + -- As noted by Note [Eta expanding primops] in GHC.Builtin.PrimOps + -- we require that primop applications be saturated. + PrimOpId op -> ASSERT( saturated ) + StgOpApp (StgPrimOp op) args' res_ty -- A call to some primitive Cmm function. FCallId (CCall (CCallSpec (StaticTarget _ lbl (Just pkgId) True) ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -71,7 +71,7 @@ import qualified Data.Set as S The goal of this pass is to prepare for code generation. -1. Saturate constructor applications. +1. Saturate constructor and primop applications. 2. Convert to A-normal form; that is, function arguments are always variables. @@ -1067,15 +1067,11 @@ maybeSaturate deals with eta expanding to saturate things that can't deal with unsaturated applications (identified by 'hasNoBinding', currently just foreign calls and unboxed tuple/sum constructors). -Note that eta expansion in CorePrep is very fragile due to the "prediction" of -CAFfyness made during tidying (see Note [CAFfyness inconsistencies due to eta -expansion in CorePrep] in GHC.Iface.Tidy for details. We previously saturated primop +Historical Note: Note that eta expansion in CorePrep used to be very fragile +due to the "prediction" of CAFfyness that we used to make during tidying. +We previously saturated primop applications here as well but due to this fragility (see #16846) we now deal with this another way, as described in Note [Primop wrappers] in GHC.Builtin.PrimOps. - -It's quite likely that eta expansion of constructor applications will -eventually break in a similar way to how primops did. We really should -eliminate this case as well. -} maybeSaturate :: Id -> CpeApp -> Int -> UniqSM CpeRhs ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -515,20 +515,12 @@ hasNoBinding :: Id -> Bool -- ^ Returns @True@ of an 'Id' which may not have a -- binding, even though it is defined in this module. --- Data constructor workers used to be things of this kind, but --- they aren't any more. Instead, we inject a binding for --- them at the CorePrep stage. --- --- 'PrimOpId's also used to be of this kind. See Note [Primop wrappers] in GHC.Builtin.PrimOps. --- for the history of this. --- --- Note that CorePrep currently eta expands things no-binding things and this --- can cause quite subtle bugs. See Note [Eta expansion of hasNoBinding things --- in CorePrep] in CorePrep for details. --- --- EXCEPT: unboxed tuples, which definitely have no binding +-- Data constructor workers used to be things of this kind, but they aren't any +-- more. Instead, we inject a binding for them at the CorePrep stage. The +-- exception to this is unboxed tuples and sums datacons, which definitely have +-- no binding hasNoBinding id = case Var.idDetails id of - PrimOpId _ -> False -- See Note [Primop wrappers] in GHC.Builtin.PrimOps + PrimOpId _ -> True -- See Note [Eta expanding primops] in GHC.Builtin.PrimOps FCallId _ -> True DataConWorkId dc -> isUnboxedTupleCon dc || isUnboxedSumCon dc _ -> isCompulsoryUnfolding (idUnfolding id) ===================================== testsuite/tests/codeGen/should_fail/T13233.hs ===================================== @@ -21,9 +21,6 @@ obscure _ = () quux :: () quux = obscure (#,#) --- It used to be that primops has no binding. However, as described in --- Note [Primop wrappers] in GHC.Builtin.PrimOps we now rewrite unsaturated primop --- applications to their wrapper, which allows safe use of levity polymorphism. primop :: forall (rep :: RuntimeRep) (a :: TYPE rep) b c. a -> b -> (State# RealWorld -> (# State# RealWorld, c #)) -> State# RealWorld -> (# State# RealWorld, Weak# b #) ===================================== testsuite/tests/codeGen/should_fail/T13233.stderr ===================================== @@ -20,3 +20,11 @@ T13233.hs:22:16: error: Levity-polymorphic arguments: a :: TYPE rep1 b :: TYPE rep2 + +T13233.hs:27:10: error: + Cannot use function with levity-polymorphic arguments: + mkWeak# :: a + -> b + -> (State# RealWorld -> (# State# RealWorld, c #)) + -> State# RealWorld + -> (# State# RealWorld, Weak# b #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de4c785c49bf99e284f51626b33ea024bfb5862b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de4c785c49bf99e284f51626b33ea024bfb5862b You're receiving 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 24 22:36:38 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 18:36:38 -0400 Subject: [Git][ghc/ghc][wip/keepAlive] 48 commits: Derive Ord instance for Extension Message-ID: <5ea369f6c6c94_616712d73b9469970d0@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/keepAlive at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - 306dba47 by Ben Gamari at 2020-04-24T16:16:37-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - b9eebc84 by Simon Peyton Jones at 2020-04-24T16:16:37-04:00 Make Lint check return type of a join point Consider join x = rhs in body It's important that the type of 'rhs' is the same as the type of 'body', but Lint wasn't checking that invariant. Now it does! This was exposed by investigation into !3113. - - - - - 891fc8b2 by Simon Peyton Jones at 2020-04-24T16:16:37-04:00 Do not float join points in exprIsConApp_maybe We hvae been making exprIsConApp_maybe cleverer in recent times: commit b78cc64e923716ac0512c299f42d4d0012306c05 Date: Thu Nov 15 17:14:31 2018 +0100 Make constructor wrappers inline only during the final phase commit 7833cf407d1f608bebb1d38bb99d3035d8d735e6 Date: Thu Jan 24 17:58:50 2019 +0100 Look through newtype wrappers (Trac #16254) commit c25b135ff5b9c69a90df0ccf51b04952c2dc6ee1 Date: Thu Feb 21 12:03:22 2019 +0000 Fix exprIsConApp_maybe But alas there was still a bug, now immortalised in Note [Don't float join points] in SimpleOpt. It's quite hard to trigger because it requires a dead join point, but it came up when compiling Cabal Cabal.Distribution.Fields.Lexer.hs, when working on !3113. Happily, the fix is extremly easy. Finding the bug was not so easy. - - - - - 8d548e83 by Ben Gamari at 2020-04-24T16:16:37-04:00 Allow simplification through runRW# Because runRW# inlines so late, we were previously able to do very little simplification across it. For instance, given even a simple program like case runRW# (\s -> let n = I# 42# in n) of I# n# -> f n# we previously had no way to avoid the allocation of the I#. This patch allows the simplifier to push strict contexts into the continuation of a runRW# application, as explained in in Note [Simplification of runRW#] in GHC.CoreToStg.Prep. Fixes #15127. Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 89ebad8d by Ben Gamari at 2020-04-24T17:08:50-04:00 genprimopcode: Add a second levity-polymorphic tyvar - - - - - 5bfe7baa by Ben Gamari at 2020-04-24T18:30:33-04:00 Implement keepAlive# - - - - - aea3605e by Ben Gamari at 2020-04-24T18:30:33-04:00 base: Use keepAlive# in withForeignPtr - - - - - c81f4732 by Ben Gamari at 2020-04-24T18:30:33-04:00 base: Use keepAlive# in alloca, et al. - - - - - 637cba30 by Ben Gamari at 2020-04-24T18:30:33-04:00 ghc-compact: Use keepAlive# - - - - - 1c4caab7 by Ben Gamari at 2020-04-24T18:30:33-04:00 XXX: Relax Note [Join points are less general than the paper] - - - - - 7624ab1b by Ben Gamari at 2020-04-24T18:30:33-04:00 XXX: Don't apply Note [dodgy unsafeCoerce 1] to join points - - - - - fd7dc8f6 by Ben Gamari at 2020-04-24T18:30:33-04:00 desugar: Eta expand runRW# - - - - - 1a75b75f by Ben Gamari at 2020-04-24T18:30:33-04:00 Give runRW# a more precise strictness signature Previously runRW# had a strictness signature of <C(S)>. This failed to capture the fact that runRW This was noticed in Giving it a more precise strictness signature which captures the one-shot nature of the state token application. - - - - - 51f194f7 by Ben Gamari at 2020-04-24T18:30:33-04:00 codeGen: A bit of debugging output - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/Regs.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Packages.hs - compiler/GHC/Driver/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9b07d93c172f6de7b78ff341401d9f755e492d85...51f194f7d0b9af680514f39c8f5878164eecb1e5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9b07d93c172f6de7b78ff341401d9f755e492d85...51f194f7d0b9af680514f39c8f5878164eecb1e5 You're receiving 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 24 23:34:12 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 19:34:12 -0400 Subject: [Git][ghc/ghc][wip/keepAlive] 4 commits: Simplify Message-ID: <5ea37774627e9_61673f81afeb5fbc7001677@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/keepAlive at Glasgow Haskell Compiler / GHC Commits: 27651ba2 by Ben Gamari at 2020-04-24T19:33:57-04:00 Simplify - - - - - 4b602e59 by Ben Gamari at 2020-04-24T19:33:58-04:00 base: Use keepAlive# in withForeignPtr - - - - - fa62af11 by Ben Gamari at 2020-04-24T19:33:58-04:00 base: Use keepAlive# in alloca, et al. - - - - - 03555271 by Ben Gamari at 2020-04-24T19:33:58-04:00 ghc-compact: Use keepAlive# - - - - - 6 changed files: - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - libraries/base/Foreign/ForeignPtr/Imp.hs - libraries/base/Foreign/Marshal/Alloc.hs - libraries/base/GHC/ForeignPtr.hs - libraries/ghc-compact/GHC/Compact/Serialized.hs Changes: ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -405,6 +405,7 @@ lvlApp :: LevelEnv lvlApp env orig_expr ((_,AnnVar fn), args) -- Try to ensure that runRW#'s continuation isn't floated out. -- See Note [Simplification of runRW#]. + -- TODO: update for keepAlive# | fn `hasKey` runRWKey || fn `hasKey` keepAliveIdKey = do { args' <- mapM (lvlExpr env) args ; return (foldl' App (lookupVar env fn) args') } ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -1882,59 +1882,11 @@ rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) ---------- Simplify continuation-passing primops -------------- -- (Do this after absorbing all arguments) --- --- Push strict contexts into keepAlive# continuation --- --- That is, --- --- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) --- ~> --- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 -rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont - | fun `hasKey` keepAliveIdKey - , [ ValArg y - , ValArg x - , TyArg {} -- res_ty - , TyArg {} -- res_rep - , TyArg {as_arg_ty=arg_ty} - , TyArg {as_arg_ty=arg_rep} - ] <- rev_args - = do { let ty' = contResultType cont - ; j <- newJoinId [] ty' - ; let env' = zapSubstEnv env - ; y' <- simplExprC env' y cont - ; let bind = NonRec j y' - ; x' <- simplExpr env' x - ; arg_rep' <- simplType env' arg_rep - ; arg_ty' <- simplType env' arg_ty - ; let call' = mkApps (Var fun) - [ mkTyArg arg_rep', mkTyArg arg_ty' - , mkTyArg (getRuntimeRep ty'), mkTyArg ty' - , x' - , Var j - ] - ; --pprTrace "rebuild keepAlive" (ppr fun $$ ppr rev_args $$ ppr cont) $ - return (emptyFloats env `extendFloats` bind, call') } - ----------- The runRW# rule. Do this after absorbing all arguments ------ --- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o --- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) -rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) - (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) - | fun `hasKey` runRWKey - , not (contIsStop cont) -- Don't fiddle around if the continuation is boring - , [ TyArg {}, TyArg {} ] <- rev_args - = do { s <- newId (fsLit "s") realWorldStatePrimTy - ; let env' = (arg_se `setInScopeFromE` env) `addNewInScopeIds` [s] - cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s - , sc_env = env', sc_cont = cont } - ; body' <- simplExprC env' arg cont' - ; let arg' = Lam s body' - ty' = contResultType cont - rr' = getRuntimeRep ty' - call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] - ; return (emptyFloats env, call') } +rebuildCall env arg_info cont + | Just do_it <- rebuildContPrimop env arg_info cont + = do_it +---------- Simplify value applications -------------- rebuildCall env info@(ArgInfo { ai_type = fun_ty, ai_encl = encl_rules , ai_strs = str:strs, ai_discs = disc:discs }) (ApplyToVal { sc_arg = arg, sc_env = arg_se @@ -1986,6 +1938,72 @@ rebuildCall env info@(ArgInfo { ai_type = fun_ty, ai_encl = encl_rules rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +-- | A few primops take the form of: +-- +-- @ +-- op :: ... -> a -> a +-- @ +-- +-- and have semantics which permit us to "extend the reach" of their +-- continuation. For instance, see Note [Simplifying runRW#]. +-- +-- Push strict contexts into keepAlive# continuation +-- +-- That is, +-- +-- K[keepAlive# @arg_rep @arg_ty @res_rep @res_ty x (\s -> rhs) s0] :: (out_ty :: TYPE out_rep) +-- ~> +-- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 +rebuildContPrimop :: SimplEnv -> ArgInfo -> SimplCont -> Maybe (SimplM (SimplFloats, OutExpr)) +rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont + | fun `hasKey` keepAliveIdKey + , [ ValArg y + , ValArg x + , TyArg {} -- res_ty + , TyArg {} -- res_rep + , TyArg {as_arg_ty=arg_ty} + , TyArg {as_arg_ty=arg_rep} + ] <- rev_args + = Just $ do + { let ty' = contResultType cont + ; j <- newJoinId [] ty' + ; let env' = zapSubstEnv env + ; y' <- simplExprC env' y cont + ; let bind = NonRec j y' + ; x' <- simplExpr env' x + ; arg_rep' <- simplType env' arg_rep + ; arg_ty' <- simplType env' arg_ty + ; let call' = mkApps (Var fun) + [ mkTyArg arg_rep', mkTyArg arg_ty' + , mkTyArg (getRuntimeRep ty'), mkTyArg ty' + , x' + , Var j + ] + ; --pprTrace "rebuild keepAlive" (ppr fun $$ ppr rev_args $$ ppr cont) $ + return (emptyFloats env `extendFloats` bind, call') } + +-- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o +-- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) +rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) + (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) + | fun `hasKey` runRWKey + , not (contIsStop cont) -- Don't fiddle around if the continuation is boring + , [ TyArg {}, TyArg {} ] <- rev_args + = Just $ do + { s <- newId (fsLit "s") realWorldStatePrimTy + ; let env' = (arg_se `setInScopeFromE` env) `addNewInScopeIds` [s] + cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s + , sc_env = env', sc_cont = cont } + ; body' <- simplExprC env' arg cont' + ; let arg' = Lam s body' + ty' = contResultType cont + rr' = getRuntimeRep ty' + call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] + ; return (emptyFloats env, call') } + +rebuildContPrimop _ _ _ = Nothing + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet ===================================== libraries/base/Foreign/ForeignPtr/Imp.hs ===================================== @@ -66,31 +66,6 @@ newForeignPtr finalizer p addForeignPtrFinalizer finalizer fObj return fObj -withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b --- ^This is a way to look at the pointer living inside a --- foreign object. This function takes a function which is --- applied to that pointer. The resulting 'IO' action is then --- executed. The foreign object is kept alive at least during --- the whole action, even if it is not used directly --- inside. Note that it is not safe to return the pointer from --- the action and use it after the action completes. All uses --- of the pointer should be inside the --- 'withForeignPtr' bracket. The reason for --- this unsafeness is the same as for --- 'unsafeForeignPtrToPtr' below: the finalizer --- may run earlier than expected, because the compiler can only --- track usage of the 'ForeignPtr' object, not --- a 'Ptr' object made from it. --- --- This function is normally used for marshalling data to --- or from the object pointed to by the --- 'ForeignPtr', using the operations from the --- 'Storable' class. -withForeignPtr fo io - = do r <- io (unsafeForeignPtrToPtr fo) - touchForeignPtr fo - return r - -- | This variant of 'newForeignPtr' adds a finalizer that expects an -- environment in addition to the finalized pointer. The environment -- that will be passed to the finalizer is fixed by the second argument to ===================================== libraries/base/Foreign/Marshal/Alloc.hs ===================================== @@ -68,6 +68,7 @@ import GHC.IO.Exception import GHC.Real import GHC.Ptr import GHC.Base +import GHC.Prim ( keepAlive# ) -- exported functions -- ------------------ @@ -116,19 +117,6 @@ alloca :: forall a b . Storable a => (Ptr a -> IO b) -> IO b alloca = allocaBytesAligned (sizeOf (undefined :: a)) (alignment (undefined :: a)) --- Note [NOINLINE for touch#] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~ --- Both allocaBytes and allocaBytesAligned use the touch#, which is notoriously --- fragile in the presence of simplification (see #14346). In particular, the --- simplifier may drop the continuation containing the touch# if it can prove --- that the action passed to allocaBytes will not return. The hack introduced to --- fix this for 8.2.2 is to mark allocaBytes as NOINLINE, ensuring that the --- simplifier can't see the divergence. --- --- These can be removed once #14375 is fixed, which suggests that we instead do --- away with touch# in favor of a primitive that will capture the scoping left --- implicit in the case of touch#. - -- |@'allocaBytes' n f@ executes the computation @f@, passing as argument -- a pointer to a temporarily allocated block of memory of @n@ bytes. -- The block of memory is sufficiently aligned for any of the basic @@ -142,13 +130,9 @@ allocaBytes (I# size) action = IO $ \ s0 -> case newPinnedByteArray# size s0 of { (# s1, mbarr# #) -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> let addr = Ptr (byteArrayContents# barr#) in - case action addr of { IO action' -> - case action' s2 of { (# s3, r #) -> - case touch# barr# s3 of { s4 -> - (# s4, r #) - }}}}} --- See Note [NOINLINE for touch#] -{-# NOINLINE allocaBytes #-} + case action addr of { IO action' -> + keepAlive# barr# (action' s2) + }}} allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 -> @@ -156,12 +140,8 @@ allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> let addr = Ptr (byteArrayContents# barr#) in case action addr of { IO action' -> - case action' s2 of { (# s3, r #) -> - case touch# barr# s3 of { s4 -> - (# s4, r #) - }}}}} --- See Note [NOINLINE for touch#] -{-# NOINLINE allocaBytesAligned #-} + keepAlive# barr# (action' s2) + }}} -- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes' -- to the size needed to store values of type @b at . The returned pointer ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -37,6 +37,7 @@ module GHC.ForeignPtr mallocPlainForeignPtrAlignedBytes, addForeignPtrFinalizer, addForeignPtrFinalizerEnv, + withForeignPtr, touchForeignPtr, unsafeForeignPtrToPtr, castForeignPtr, @@ -54,6 +55,7 @@ import GHC.Base import GHC.IORef import GHC.STRef ( STRef(..) ) import GHC.Ptr ( Ptr(..), FunPtr(..) ) +import GHC.Prim ( keepAlive# ) import Unsafe.Coerce ( unsafeCoerce, unsafeCoerceUnlifted ) @@ -388,6 +390,31 @@ newForeignPtr_ (Ptr obj) = do r <- newIORef NoFinalizers return (ForeignPtr obj (PlainForeignPtr r)) +withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b +-- ^This is a way to look at the pointer living inside a +-- foreign object. This function takes a function which is +-- applied to that pointer. The resulting 'IO' action is then +-- executed. The foreign object is kept alive at least during +-- the whole action, even if it is not used directly +-- inside. Note that it is not safe to return the pointer from +-- the action and use it after the action completes. All uses +-- of the pointer should be inside the +-- 'withForeignPtr' bracket. The reason for +-- this unsafeness is the same as for +-- 'unsafeForeignPtrToPtr' below: the finalizer +-- may run earlier than expected, because the compiler can only +-- track usage of the 'ForeignPtr' object, not +-- a 'Ptr' object made from it. +-- +-- This function is normally used for marshalling data to +-- or from the object pointed to by the +-- 'ForeignPtr', using the operations from the +-- 'Storable' class. +withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> + case f (unsafeForeignPtrToPtr fo) of + IO action# -> keepAlive# r (action# s) + + touchForeignPtr :: ForeignPtr a -> IO () -- ^This function ensures that the foreign object in -- question is alive at the given place in the sequence of IO ===================================== libraries/ghc-compact/GHC/Compact/Serialized.hs ===================================== @@ -74,12 +74,6 @@ mkBlockList buffer = compactGetFirstBlock buffer >>= go rest <- go next return $ item : rest --- We MUST mark withSerializedCompact as NOINLINE --- Otherwise the compiler will eliminate the call to touch# --- causing the Compact# to be potentially GCed too eagerly, --- before func had a chance to copy everything into its own --- buffers/sockets/whatever - -- | Serialize the 'Compact', and call the provided function with -- with the 'Compact' serialized representation. It is not safe -- to return the pointer from the action and use it after @@ -89,7 +83,6 @@ mkBlockList buffer = compactGetFirstBlock buffer >>= go -- unsound to use 'unsafeInterleaveIO' to lazily construct -- a lazy bytestring from the 'Ptr'. -- -{-# NOINLINE withSerializedCompact #-} withSerializedCompact :: Compact a -> (SerializedCompact a -> IO c) -> IO c withSerializedCompact (Compact buffer root lock) func = withMVar lock $ \_ -> do @@ -97,9 +90,7 @@ withSerializedCompact (Compact buffer root lock) func = withMVar lock $ \_ -> do (# s', rootAddr #) -> (# s', Ptr rootAddr #) ) blockList <- mkBlockList buffer let serialized = SerializedCompact blockList rootPtr - r <- func serialized - IO (\s -> case touch# buffer s of - s' -> (# s', r #) ) + IO (\s1 -> case func serialized of IO action' -> keepAlive# buffer (action' s1)) fixupPointers :: Addr# -> Addr# -> State# RealWorld -> (# State# RealWorld, Maybe (Compact a) #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/51f194f7d0b9af680514f39c8f5878164eecb1e5...0355527190c61abea8ff4b7bb2c81510ae23b7d9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/51f194f7d0b9af680514f39c8f5878164eecb1e5...0355527190c61abea8ff4b7bb2c81510ae23b7d9 You're receiving 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 24 23:54:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 24 Apr 2020 19:54:48 -0400 Subject: [Git][ghc/ghc][wip/keepAlive] hi Message-ID: <5ea37c481a9fa_61673f81cd0d79187002537@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/keepAlive at Glasgow Haskell Compiler / GHC Commits: e2d1c152 by Ben Gamari at 2020-04-24T19:47:42-04:00 hi - - - - - 8 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -2199,14 +2199,13 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, - keepAliveIdKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey + :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 oneShotKey = mkPreludeMiscIdUnique 106 runRWKey = mkPreludeMiscIdUnique 107 -keepAliveIdKey = mkPreludeMiscIdUnique 108 traceKey :: Unique traceKey = mkPreludeMiscIdUnique 109 ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3239,9 +3239,11 @@ primop SeqOp "seq#" GenPrimOp a -> State# s -> (# State# s, a #) -- See Note [seq# magic] in GHC.Core.Op.ConstantFold -pseudoop "keepAlive#" +primop KeepAliveOp "keepAlive#" GenPrimOp o -> p -> p { TODO. } + with + strictness = { \ _arity -> mkClosedStrictSig [topDmd, strictApply1Dmd] topDiv } primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -927,7 +927,7 @@ lintCoreExpr e@(App _ _) = failWithL (text "Invalid runRW# application") | Var fun <- fun - , fun `hasKey` keepAliveIdKey + , Just KeepAliveOp <- isPrimOpId_maybe f , [arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5, arg6] <- args = do { fun_ty6 <- lintCoreArgs (idType fun) [ arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5 ] @@ -936,7 +936,7 @@ lintCoreExpr e@(App _ _) } | Var fun <- fun - , fun `hasKey` keepAliveIdKey + , Just KeepAliveOp <- isPrimOpId_maybe f = failWithL (text "Invalid keepAlive# application") | otherwise ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -98,7 +98,7 @@ import GHC.Types.Basic ( Arity, RecFlag(..), isRec ) import GHC.Core.DataCon ( dataConOrigResTy ) import GHC.Builtin.Types import GHC.Types.Unique.Supply -import GHC.Builtin.Names ( runRWKey, keepAliveIdKey ) +import GHC.Builtin.Names ( runRWKey ) import Util import Outputable import FastString @@ -398,6 +398,12 @@ lvlNonTailExpr env expr = lvlExpr (placeJoinCeiling env) expr ------------------------------------------- +isContPrimOp :: Id -> Bool +isContPrimOp fn + | fn `hasKey` runRWKey = True + | Just KeepAliveOp <- isPrimOpId_maybe fn = True + | otherwise = Falsej + lvlApp :: LevelEnv -> CoreExprWithFVs -> (CoreExprWithFVs, [CoreExprWithFVs]) -- Input application @@ -406,7 +412,7 @@ lvlApp env orig_expr ((_,AnnVar fn), args) -- Try to ensure that runRW#'s continuation isn't floated out. -- See Note [Simplification of runRW#]. -- TODO: update for keepAlive# - | fn `hasKey` runRWKey || fn `hasKey` keepAliveIdKey + | isContPrimOp fn = do { args' <- mapM (lvlExpr env) args ; return (foldl' App (lookupVar env fn) args') } ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -38,7 +38,7 @@ import GHC.Core.DataCon import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) ) import GHC.Core import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) -import GHC.Builtin.Names( runRWKey, keepAliveIdKey ) +import GHC.Builtin.Names( runRWKey ) import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) import GHC.Types.Cpr ( mkCprSig, botCpr ) @@ -1956,7 +1956,7 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 rebuildContPrimop :: SimplEnv -> ArgInfo -> SimplCont -> Maybe (SimplM (SimplFloats, OutExpr)) rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont - | fun `hasKey` keepAliveIdKey + | Just KeepAliveOp <- isPrimOpId_maybe fun , [ ValArg y , ValArg x , TyArg {} -- res_ty ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -868,7 +868,7 @@ cpeApp top_env expr cpe_app env (Var f) [CpeApp (Type arg_rep), CpeApp (Type arg_ty), CpeApp (Type _result_rep), CpeApp (Type result_ty), CpeApp x, CpeApp y] 2 - | f `hasKey` keepAliveIdKey + | Just KeepAliveOp <- isPrimOpId_maybe f = do { y' <- newVar result_ty ; s2 <- newVar realWorldStatePrimTy ; let touchId = mkPrimOpId TouchOp @@ -878,7 +878,7 @@ cpeApp top_env expr ; pprTrace "cpe_app" (ppr expr) $ cpeBody env expr } cpe_app _env (Var f) args n - | f `hasKey` keepAliveIdKey + | Just KeepAliveOp <- isPrimOpId_maybe f = pprPanic "cpe_app(keepAlive#)" (ppr args $$ ppr n) cpe_app env (Var v) args depth ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -55,7 +55,6 @@ import GHC.Core.Type import GHC.Types.RepType import GHC.Types.SrcLoc import GHC.Types.Unique ( hasKey ) -import GHC.Builtin.Names ( keepAliveIdKey ) import Outputable import GHC.Types.Module ( Module ) import qualified ErrUtils as Err @@ -106,9 +105,7 @@ lintStgArg (StgLitArg _) = return () lintStgArg (StgVarArg v) = lintStgVar v lintStgVar :: Id -> LintM () -lintStgVar id - | id `hasKey` keepAliveIdKey = addErrL (text "keepAlive# not permitted in STG") - | otherwise = checkInScope id +lintStgVar id = checkInScope id lintStgBinds :: (OutputablePass a, BinderP a ~ Id) @@ -186,6 +183,9 @@ lintStgExpr app@(StgConApp con args _arg_tys) = do mapM_ lintStgArg args mapM_ checkPostUnariseConArg args +lintStgExpr (StgOpApp (StgPrimOp KeepAliveOp) _ _) = + addErrL (text "keepAlive# should have been desugared by CorePrep") + lintStgExpr (StgOpApp _ args _) = mapM_ lintStgArg args ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -158,7 +158,6 @@ ghcPrimIds , magicDictId , coerceId , proxyHashId - , keepAliveId ] {- @@ -1353,8 +1352,7 @@ another gun with which to shoot yourself in the foot. nullAddrName, seqName, realWorldName, voidPrimIdName, coercionTokenName, - magicDictName, coerceName, proxyName, - keepAliveName :: Name + magicDictName, coerceName, proxyName :: Name nullAddrName = mkWiredInIdName gHC_PRIM (fsLit "nullAddr#") nullAddrIdKey nullAddrId seqName = mkWiredInIdName gHC_PRIM (fsLit "seq") seqIdKey seqId realWorldName = mkWiredInIdName gHC_PRIM (fsLit "realWorld#") realWorldPrimIdKey realWorldPrimId @@ -1363,7 +1361,6 @@ coercionTokenName = mkWiredInIdName gHC_PRIM (fsLit "coercionToken#") coercionT magicDictName = mkWiredInIdName gHC_PRIM (fsLit "magicDict") magicDictKey magicDictId coerceName = mkWiredInIdName gHC_PRIM (fsLit "coerce") coerceKey coerceId proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHashKey proxyHashId -keepAliveName = mkWiredInIdName gHC_PRIM (fsLit "keepAlive#") keepAliveIdKey keepAliveId lazyIdName, oneShotName, noinlineIdName :: Name lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId @@ -1422,27 +1419,6 @@ seqId = pcMiscPrelId seqName ty info rhs = mkLams ([runtimeRep2TyVar, alphaTyVar, openBetaTyVar, x, y]) $ Case (Var x) x openBetaTy [(DEFAULT, [], Var y)] ------------------------------------------------- -keepAliveId :: Id -keepAliveId - = pcMiscPrelId keepAliveName ty id_info - `setIdDetails` NoBindingId - where - -- keepAlive# - -- :: forall (rep_a :: RuntimeRep) (a :: TYPE rep_a) - -- (rep_r :: RuntimeRep) (r :: TYPE rep_r). - -- a -> r -> r - -- - rep_a = runtimeRep1TyVar - a = openAlphaTyVar - rep_r = runtimeRep2TyVar - r = openBetaTyVar - ty = mkInvForAllTys [rep_a, a, rep_r, r] - $ mkVisFunTys [mkTyVarTy a, mkTyVarTy r] (mkTyVarTy r) - id_info = noCafIdInfo - `setStrictnessInfo` mkClosedStrictSig [topDmd, strictApply1Dmd, topDmd] topDiv - `setArityInfo` 3 - ------------------------------------------------ lazyId :: Id -- See Note [lazyId magic] lazyId = pcMiscPrelId lazyIdName ty info View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2d1c15280223204390ad37c4d0ecbbf9a1348fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2d1c15280223204390ad37c4d0ecbbf9a1348fb You're receiving 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 25 13:34:25 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Sat, 25 Apr 2020 09:34:25 -0400 Subject: [Git][ghc/ghc][wip/lexical-negation] 8 commits: Create di_scoped_tvs for associated data family instances properly Message-ID: <5ea43c61f4051_616712d73b947034792@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/lexical-negation at Glasgow Haskell Compiler / GHC Commits: cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - 77d77a48 by Vladislav Zavialov at 2020-04-25T16:34:17+03:00 Implement -XLexicalNegation (GHC Proposal #229) This patch introduces a new extension, -XLexicalNegation, which detects whether the minus sign stands for negation or subtraction using the whitespace-based rules described in GHC Proposal #229. - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.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/1010cc5f62774d4137b171ba2e9de811c47c5729...77d77a480878232947e78126babc4b7125c6c7b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1010cc5f62774d4137b171ba2e9de811c47c5729...77d77a480878232947e78126babc4b7125c6c7b1 You're receiving 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 25 13:59:10 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 25 Apr 2020 09:59:10 -0400 Subject: [Git][ghc/ghc][wip/caf-cleanups] 145 commits: Do not panic on linker errors Message-ID: <5ea4422e3b68b_61673f81cd9bfa6c7041736@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/caf-cleanups at Glasgow Haskell Compiler / GHC Commits: 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - 7eb451f9 by Ben Gamari at 2020-04-25T09:58:52-04:00 Add few cleanups of the CAF logic - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - compiler/prelude/PrimOp.hs-boot → compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4a147e7eb82883c70683da2682d5596287e196a6...7eb451f9cb25f316a94f470943ca3e9747d9e2a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4a147e7eb82883c70683da2682d5596287e196a6...7eb451f9cb25f316a94f470943ca3e9747d9e2a7 You're receiving 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 25 14:46:35 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Sat, 25 Apr 2020 10:46:35 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sjakobi/undeprecate-first-last Message-ID: <5ea44d4b453c9_6167135b148c704521@gitlab.haskell.org.mail> Simon Jakobi pushed new branch wip/sjakobi/undeprecate-first-last at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/undeprecate-first-last You're receiving 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 25 16:16:38 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Sat, 25 Apr 2020 12:16:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/open-telemetry Message-ID: <5ea462668a0eb_61673f813dcf07f870543f3@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/open-telemetry at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/open-telemetry You're receiving 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 25 22:48:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 25 Apr 2020 18:48:22 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc/fix-bitmap-clear Message-ID: <5ea4be36b956_61673f81cd9bfa6c7112093@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/gc/fix-bitmap-clear at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc/fix-bitmap-clear You're receiving 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 25 22:51:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 25 Apr 2020 18:51:36 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/backports Message-ID: <5ea4bef8b513b_61673f81cd4c695c71147f3@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/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 Sun Apr 26 01:24:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 25 Apr 2020 21:24:05 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Trees That Grow refactor for `ConPat` and `CoPat` Message-ID: <5ea4e2b59b354_6167683c0d871219a5@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - 02d2bfd9 by Sylvain Henry at 2020-04-24T15:46:27+02:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 178202d8 by Sylvain Henry at 2020-04-25T21:23:59-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 30 changed files: - 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/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4c6190d248f0dbe4af1b307c13cb47978495d9f0...178202d82087816a394d0d12eaeee57d78dab2b4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4c6190d248f0dbe4af1b307c13cb47978495d9f0...178202d82087816a394d0d12eaeee57d78dab2b4 You're receiving 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 26 06:54:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 26 Apr 2020 02:54:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Fix misleading Ptr phantom type in SerializedCompact (#15653) Message-ID: <5ea53020ba21d_61673f81cd9bfa6c71408f7@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ae3785bb by Sylvain Henry at 2020-04-26T02:54:21-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 1 changed file: - libraries/ghc-compact/GHC/Compact/Serialized.hs Changes: ===================================== libraries/ghc-compact/GHC/Compact/Serialized.hs ===================================== @@ -47,8 +47,8 @@ import GHC.Compact -- sent out of band in advance if the data is to be sent over RDMA -- (which requires both sender and receiver to have pinned buffers). data SerializedCompact a = SerializedCompact - { serializedCompactBlockList :: [(Ptr a, Word)] - , serializedCompactRoot :: Ptr a + { serializedCompactBlockList :: [(Ptr (), Word)] + , serializedCompactRoot :: Ptr () } addrIsNull :: Addr# -> Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ae3785bbc8a0acaa2ccd0354397451003d405358 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ae3785bbc8a0acaa2ccd0354397451003d405358 You're receiving 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 26 12:24:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 26 Apr 2020 08:24:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Fix misleading Ptr phantom type in SerializedCompact (#15653) Message-ID: <5ea57d9017ce8_6167120888bc716509@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 31748cc8 by Sylvain Henry at 2020-04-26T08:24:44-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 1 changed file: - libraries/ghc-compact/GHC/Compact/Serialized.hs Changes: ===================================== libraries/ghc-compact/GHC/Compact/Serialized.hs ===================================== @@ -47,8 +47,8 @@ import GHC.Compact -- sent out of band in advance if the data is to be sent over RDMA -- (which requires both sender and receiver to have pinned buffers). data SerializedCompact a = SerializedCompact - { serializedCompactBlockList :: [(Ptr a, Word)] - , serializedCompactRoot :: Ptr a + { serializedCompactBlockList :: [(Ptr (), Word)] + , serializedCompactRoot :: Ptr () } addrIsNull :: Addr# -> Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/31748cc869bb6ebca7a1c36801216abe0b02e1e0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/31748cc869bb6ebca7a1c36801216abe0b02e1e0 You're receiving 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 26 17:55:27 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 26 Apr 2020 13:55:27 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5ea5cb0f32835_6167683c0d87230976@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 30 changed files: - 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/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/31748cc869bb6ebca7a1c36801216abe0b02e1e0...22bf5c738e0339fa12940414d6448896c6733808 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/31748cc869bb6ebca7a1c36801216abe0b02e1e0...22bf5c738e0339fa12940414d6448896c6733808 You're receiving 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 26 20:24:57 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 26 Apr 2020 16:24:57 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18103 Message-ID: <5ea5ee19a1bdc_61673f81cd4c695c72661cd@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18103 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18103 You're receiving 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 26 22:11:23 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Sun, 26 Apr 2020 18:11:23 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 4 commits: Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Message-ID: <5ea6070b9caa2_61673f81cc913ba0727653b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: ddae31fb by Sebastian Graf at 2020-04-24T12:00:54+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - df4ed5c7 by Sebastian Graf at 2020-04-24T12:50:41+02:00 Fix primop termination - - - - - f644a361 by Sebastian Graf at 2020-04-26T23:53:03+02:00 Test for DataCon wrapper CPR - - - - - d9cba900 by Sebastian Graf at 2020-04-27T00:11:12+02:00 Fix CPR of bottoming functions/primops - - - - - 13 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Id/Make.hs - libraries/integer-gmp/src/GHC/Integer/Type.hs - + testsuite/tests/cpranal/sigs/DataConWrapperCpr.hs - + testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr - testsuite/tests/cpranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -798,7 +798,7 @@ aBSENT_SUM_FIELD_ERROR_ID = mkVanillaGlobalWithInfo absentSumFieldErrorName (mkSpecForAllTys [alphaTyVar] (mkTyVarTy alphaTyVar)) -- forall a . a (vanillaIdInfo `setStrictnessInfo` mkClosedStrictSig [] botDiv - `setCprInfo` mkCprSig 0 botCpr + `setCprInfo` mkCprSig 0 divergeCpr `setArityInfo` 0 `setCafInfo` NoCafRefs) -- #15038 @@ -813,7 +813,7 @@ mkRuntimeErrorId name = mkVanillaGlobalWithInfo name runtimeErrorTy bottoming_info where bottoming_info = vanillaIdInfo `setStrictnessInfo` strict_sig - `setCprInfo` mkCprSig 1 botCpr + `setCprInfo` mkCprSig 1 divergeCpr `setArityInfo` 1 -- Make arity and strictness agree ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -13,8 +13,7 @@ ToDo: -} {-# LANGUAGE CPP, RankNTypes, PatternSynonyms, ViewPatterns, RecordWildCards, - DeriveFunctor #-} -{-# LANGUAGE LambdaCase #-} + DeriveFunctor, LambdaCase, TypeApplications #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.ConstantFold @@ -249,18 +248,19 @@ primOpRules nm = \case , inversePrimOp FloatNegOp ] -- Double - DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) - , identity zerod ] - DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) - , rightIdentity zerod ] - DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) - , identity oned - , strengthReduction twod DoubleAddOp ] + DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) + , identity zerod ] + DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) + , rightIdentity zerod ] + DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) + , identity oned + , strengthReduction twod DoubleAddOp ] -- zeroElem zerod doesn't hold because of NaN - DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) - , rightIdentity oned ] - DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp - , inversePrimOp DoubleNegOp ] + DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) + , rightIdentity oned ] + DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp + , inversePrimOp DoubleNegOp ] + DoubleDecode_Int64Op -> mkPrimOpRule nm 1 [ unaryLit doubleDecodeOp ] -- Relational operators @@ -510,6 +510,22 @@ doubleOp2 op env (LitDouble f1) (LitDouble f2) = Just (mkDoubleVal env (f1 `op` f2)) doubleOp2 _ _ _ _ = Nothing +-------------------------- +doubleDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr +doubleDecodeOp env (LitDouble ((decodeFloat . fromRational @Double) -> (m, e))) + = Just $ mkCoreUbxTup [iNT64Ty, intPrimTy] + [ Lit (mkLitINT64 (roPlatform env) (toInteger m)) + , mkIntVal platform (toInteger e) ] + where + platform = roPlatform env + (iNT64Ty, mkLitINT64) + | platformWordSizeInBits platform < 64 + = (int64PrimTy, mkLitInt64Wrap) + | otherwise + = (intPrimTy , mkLitIntWrap) +doubleDecodeOp _ _ + = Nothing + -------------------------- {- Note [The litEq rule: converting equality to case] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1317,7 +1333,6 @@ builtinIntegerRules = rule_encodeFloat "encodeFloatInteger" encodeFloatIntegerName mkFloatLitFloat, rule_convert "floatFromInteger" floatFromIntegerName (\_ -> mkFloatLitFloat), rule_encodeFloat "encodeDoubleInteger" encodeDoubleIntegerName mkDoubleLitDouble, - rule_decodeDouble "decodeDoubleInteger" decodeDoubleIntegerName, rule_convert "doubleFromInteger" doubleFromIntegerName (\_ -> mkDoubleLitDouble), rule_rationalTo "rationalToFloat" rationalToFloatName mkFloatExpr, rule_rationalTo "rationalToDouble" rationalToDoubleName mkDoubleExpr, @@ -1390,9 +1405,6 @@ builtinIntegerRules = rule_encodeFloat str name op = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 2, ru_try = match_Integer_Int_encodeFloat op } - rule_decodeDouble str name - = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, - ru_try = match_decodeDouble } rule_XToIntegerToX str name toIntegerName = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, ru_try = match_XToIntegerToX toIntegerName } @@ -1747,22 +1759,6 @@ match_rationalTo mkLit _ id_unf _ [xl, yl] = Just (mkLit (fromRational (x % y))) match_rationalTo _ _ _ _ _ = Nothing -match_decodeDouble :: RuleFun -match_decodeDouble env id_unf fn [xl] - | Just (LitDouble x) <- exprIsLiteral_maybe id_unf xl - = case splitFunTy_maybe (idType fn) of - Just (_, res) - | Just [_lev1, _lev2, integerTy, intHashTy] <- tyConAppArgs_maybe res - -> case decodeFloat (fromRational x :: Double) of - (y, z) -> - Just $ mkCoreUbxTup [integerTy, intHashTy] - [Lit (mkLitInteger y integerTy), - Lit (mkLitInt (roPlatform env) (toInteger z))] - _ -> - pprPanic "match_decodeDouble: Id has the wrong type" - (ppr fn <+> dcolon <+> ppr (idType fn)) -match_decodeDouble _ _ _ _ = Nothing - match_XToIntegerToX :: Name -> RuleFun match_XToIntegerToX n _ _ _ [App (Var x) y] | idName x == n ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -208,7 +208,7 @@ cprAnal' env args (Case scrut case_bndr ty alts) -- Regardless of whether scrut had the CPR property or not, the case binder -- certainly has it. See 'extendEnvForDataAlt'. (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args case_bndr case_bndr_ty) alts - res_ty = foldl' lubCprType botCprType alt_tys `bothCprType` whnf_flag + res_ty = lubCprTypes alt_tys `bothCprType` whnf_flag cprAnal' env args (Let (NonRec id rhs) body) = (body_ty, Let (NonRec id' rhs') body') @@ -279,7 +279,7 @@ cprFix cprFix top_lvl env str orig_pairs = loop 1 initial_pairs where - init_sig id = mkCprSig (idArity id) initRecFunCpr + init_sig id = mkCprSig (idArity id) divergeCpr -- See Note [Initialising strictness] in GHC.Core.Opt.DmdAnal initial_pairs | ae_virgin env = [(setIdCprInfo id (init_sig id), rhs) | (id, rhs) <- orig_pairs ] | otherwise = orig_pairs @@ -328,7 +328,7 @@ pruneSig d (CprSig cpr_ty) -- of functions like iterate, which we would CPR -- multiple levels deep, thereby changing termination -- behavior. - = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty `lubCpr` initRecFunCpr) } + = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty `lubCpr` divergeCpr) } unboxingStrategy :: AnalEnv -> UnboxingStrategy unboxingStrategy env ty dmd ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -88,7 +88,7 @@ import GHC.Types.Unique.DSet ( getUniqDSet ) import GHC.Types.Var.Env import GHC.Types.Literal ( litIsTrivial ) import GHC.Types.Demand ( StrictSig, Demand, isStrictDmd, splitStrictSig, increaseStrictSigArity ) -import GHC.Types.Cpr ( mkCprSig, botCpr ) +import GHC.Types.Cpr ( mkCprSig, divergeCpr ) import GHC.Types.Name ( getOccName, mkSystemVarName ) import GHC.Types.Name.Occurrence ( occNameString ) import GHC.Core.Type ( Type, mkLamTypes, splitTyConApp_maybe, tyCoVarsOfType @@ -984,7 +984,7 @@ annotateBotStr id n_extra mb_str Nothing -> id Just (arity, sig) -> id `setIdArity` (arity + n_extra) `setIdStrictness` (increaseStrictSigArity n_extra sig) - `setIdCprInfo` mkCprSig (arity + n_extra) botCpr + `setIdCprInfo` mkCprSig (arity + n_extra) divergeCpr notWorthFloating :: CoreExpr -> [Var] -> Bool -- Returns True if the expression would be replaced by ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) ) import GHC.Core import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) -import GHC.Types.Cpr ( mkCprSig, botCpr ) +import GHC.Types.Cpr ( mkCprSig, divergeCpr ) import GHC.Core.Ppr ( pprCoreExpr ) import GHC.Core.Unfold import GHC.Core.Utils @@ -739,7 +739,7 @@ addLetBndrInfo new_bndr new_arity is_bot new_unf info4 | is_bot = info3 `setStrictnessInfo` mkClosedStrictSig (replicate new_arity topDmd) botDiv - `setCprInfo` mkCprSig new_arity botCpr + `setCprInfo` mkCprSig new_arity divergeCpr | otherwise = info3 -- Zap call arity info. We have used it by now (via ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -1255,7 +1255,7 @@ mk_absent_let dflags fam_envs arg = WARN( True, text "No absent value for" <+> ppr arg_ty ) Nothing -- Can happen for 'State#' and things of 'VecRep' where - lifted_arg = arg `setIdStrictness` botSig `setIdCprInfo` mkCprSig 0 botCpr + lifted_arg = arg `setIdStrictness` botSig `setIdCprInfo` mkCprSig 0 divergeCpr -- Note in strictness signature that this is bottoming -- (for the sake of the "empty case scrutinee not known to -- diverge for sure lint" warning) ===================================== compiler/GHC/Iface/Tidy.hs ===================================== @@ -40,7 +40,7 @@ import GHC.Types.Id.Info import GHC.Core.InstEnv import GHC.Core.Type ( tidyTopType ) import GHC.Types.Demand ( appIsBottom, isTopSig, isBottomingSig ) -import GHC.Types.Cpr ( mkCprSig, botCpr ) +import GHC.Types.Cpr ( mkCprSig, divergeCpr ) import GHC.Types.Basic import GHC.Types.Name hiding (varName) import GHC.Types.Name.Set @@ -1223,7 +1223,7 @@ tidyTopIdInfo dflags rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold cpr = cprInfo idinfo final_cpr | Just _ <- mb_bot_str - = mkCprSig arity botCpr + = mkCprSig arity divergeCpr | otherwise = cpr ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -10,8 +10,8 @@ -- and "GHC.Core.Opt.WorkWrap.Utils" are its primary customers via 'idCprInfo'. module GHC.Types.Cpr ( TerminationFlag (Terminates), - Cpr, topCpr, botCpr, conCpr, whnfTermCpr, initRecFunCpr, lubCpr, asConCpr, - CprType (..), topCprType, botCprType, whnfTermCprType, conCprType, lubCprType, + Cpr, topCpr, conCpr, whnfTermCpr, divergeCpr, lubCpr, asConCpr, + CprType (..), topCprType, whnfTermCprType, conCprType, lubCprType, lubCprTypes, pruneDeepCpr, markConCprType, splitConCprTy, applyCprTy, abstractCprTy, abstractCprTyNTimes, ensureCprTyArity, trimCprTy, forceCprTy, forceCpr, bothCprType, @@ -194,12 +194,17 @@ topCpr = Cpr MightDiverge Top whnfTermCpr :: Cpr whnfTermCpr = Cpr Terminates Top --- | The initial termination of a recursive function in fixed-point iteration. --- We assume a recursive call 'MightDiverge', but are optimistic about all --- CPR and nested termination information. I.e., we assume that evaluating --- returned tuple components 'Terminates' rapidly. -initRecFunCpr :: Cpr -initRecFunCpr = Cpr MightDiverge Bot +-- | Used as +-- +-- * The initial CPR of a recursive function in fixed-point iteration +-- * The CPR of 'undefined'/'error'/other sources of divergence. +-- +-- We assume that evaluation to WHNF surely diverges (so 'MightDiverge'), but +-- are optimistic about all CPR and nested termination information. I.e., we +-- assume that returned tuple components terminate rapidly and construct a +-- product. +divergeCpr :: Cpr +divergeCpr = Cpr MightDiverge Bot conCpr :: TerminationFlag -> ConTag -> [Cpr] -> Cpr conCpr tf t fs = Cpr tf (Levitate (Con t fs)) @@ -219,7 +224,8 @@ lubCpr cpr1 cpr2 = NoMoreCpr (lubTerm (forgetCpr cpr1) (forgetCpr cpr2)) trimCpr :: Cpr -> Cpr -trimCpr = NoMoreCpr . forgetCpr +trimCpr cpr@(Cpr _ Bot) = cpr -- don't trim away bottom (we didn't do so before Nested CPR) TODO: Explain; CPR'ing for the error case +trimCpr cpr = NoMoreCpr (forgetCpr cpr) pruneDeepCpr :: Int -> Cpr -> Cpr pruneDeepCpr depth (Cpr tf (Levitate sh)) = Cpr tf (pruneKnownShape pruneDeepCpr depth sh) @@ -282,6 +288,9 @@ lubCprType ty1@(CprType n1 cpr1) ty2@(CprType n2 cpr2) | otherwise = topCprType +lubCprTypes :: [CprType] -> CprType +lubCprTypes = foldl' lubCprType botCprType + extractArgCprAndTermination :: [CprType] -> [Cpr] extractArgCprAndTermination = map go where ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -637,8 +637,6 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con -- particular, the wrapper constructor is not inlined inside -- an INLINE rhs or when it is not applied to any arguments. -- See Note [Inline partially-applied constructor wrappers] - -- Passing Nothing here allows the wrapper to inline when - -- unsaturated. wrap_unf | isNewTyCon tycon = mkCompulsoryUnfolding wrap_rhs -- See Note [Compulsory newtype unfolding] | otherwise = mkInlineUnfolding wrap_rhs @@ -1216,9 +1214,17 @@ mkPrimOpId prim_op (AnId id) UserSyntax id = mkGlobalId (PrimOpId prim_op) name ty info - -- PrimOps don't ever construct a product, but we want to preserve bottoms - cpr | isBotDiv (snd (splitStrictSig strict_sig)) = initRecFunCpr - | otherwise = whnfTermCpr + -- PrimOps never construct a product, but we want to assume that + -- 1. Cheap ones (i.e. `+#`) terminate. + -- 2. Those which have dead end Divergence (i.e. `raise#`) have + -- `divergeCpr`. If we manage to evaluate them to WHNF (which we + -- never do), they have infinitely deep CPR and termination: This is + -- so that we give an `if ... then error "blah" else (1, 2)` the + -- nested CPR property. + -- In all other cases we simply assume `topCpr`. + cpr | primOpIsCheap prim_op = whnfTermCpr + | isBottomingSig strict_sig = divergeCpr + | otherwise = topCpr info = noCafIdInfo `setRuleInfo` mkRuleInfo (maybeToList $ primOpRules name prim_op) ===================================== libraries/integer-gmp/src/GHC/Integer/Type.hs ===================================== @@ -1618,7 +1618,6 @@ foreign import ccall unsafe "integer_gmp_invert" -- Conversions to/from floating point decodeDoubleInteger :: Double# -> (# Integer, Int# #) --- decodeDoubleInteger 0.0## = (# S# 0#, 0# #) #if WORD_SIZE_IN_BITS == 64 decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# S# m#, e# #) @@ -1626,7 +1625,7 @@ decodeDoubleInteger x = case decodeDouble_Int64# x of decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# int64ToInteger m#, e# #) #endif -{-# CONSTANT_FOLDED decodeDoubleInteger #-} +{-# INLINE decodeDoubleInteger #-} -- provided by GHC's RTS foreign import ccall unsafe "__int_encodeDouble" ===================================== testsuite/tests/cpranal/sigs/DataConWrapperCpr.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} +module DataConWrapperCpr where + +data Foo = Foo !Int + +-- Should have the CPR property! Hence the wrapper $WFoo must have it. +foo :: Int -> Foo +foo = Foo ===================================== testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr ===================================== @@ -0,0 +1,12 @@ + +==================== Cpr signatures ==================== +DataConWrapperCpr.$tc'Foo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), + #, + #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), + #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *))) +DataConWrapperCpr.$tcFoo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, + #c5(*)) +DataConWrapperCpr.$trModule: #c1(#c1(#), #c1(#)) +DataConWrapperCpr.foo: #c1(#) + + ===================================== testsuite/tests/cpranal/sigs/all.T ===================================== @@ -12,3 +12,4 @@ test('CaseBinderCPR', normal, compile, ['']) test('T5075', normal, compile, ['']) test('T10694', normal, compile, ['']) test('T1600', normal, compile, ['']) +test('DataConWrapperCpr', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fec46cbba409e405f49d1aade0ad5f639a1632e4...d9cba900985a8b4d2cb17c699c47e93b61a371e7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fec46cbba409e405f49d1aade0ad5f639a1632e4...d9cba900985a8b4d2cb17c699c47e93b61a371e7 You're receiving 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 26 22:12:04 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 26 Apr 2020 18:12:04 -0400 Subject: [Git][ghc/ghc][wip/T18103] Define a Quote IO instance Message-ID: <5ea6073412751_61673f819b417d1c72774c@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18103 at Glasgow Haskell Compiler / GHC Commits: b3caaa6b by Ryan Scott at 2020-04-26T18:11:43-04:00 Define a Quote IO instance Fixes #18103. - - - - - 3 changed files: - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/quotes/T18103.hs - testsuite/tests/quotes/all.T Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -122,8 +122,7 @@ class (MonadIO m, MonadFail m) => Quasi m where ----------------------------------------------------- instance Quasi IO where - qNewName s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x)) - ; pure (mkNameU s n) } + qNewName = newNameIO qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) @@ -150,6 +149,13 @@ instance Quasi IO where qIsExtEnabled _ = badIO "isExtEnabled" qExtsEnabled = badIO "extsEnabled" +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" } ===================================== testsuite/tests/quotes/T18103.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskellQuotes #-} +module T18103 where + +import Language.Haskell.TH + +ex :: IO [Dec] +ex = [d| foo x = x |] ===================================== testsuite/tests/quotes/all.T ===================================== @@ -17,6 +17,7 @@ test('T9824', normal, compile, ['-v0']) test('T10384', normal, compile_fail, ['']) test('T16384', req_th, compile, ['']) test('T17857', normal, compile, ['']) +test('T18103', normal, compile, ['']) test('TH_tf2', normal, compile, ['-v0']) test('TH_ppr1', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3caaa6b72012f2e001754635b5ac9e4833f6163 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3caaa6b72012f2e001754635b5ac9e4833f6163 You're receiving 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 26 22:43:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 26 Apr 2020 18:43:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18105 Message-ID: <5ea60e773ee38_6167683c0d8728781f@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18105 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18105 You're receiving 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 26 22:43:20 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 26 Apr 2020 18:43:20 -0400 Subject: [Git][ghc/ghc][wip/T18105] rts: Make non-existent linker search path merely a warning Message-ID: <5ea60e881a216_61673f81cd9bfa6c72880d4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18105 at Glasgow Haskell Compiler / GHC Commits: 274ec83f by Ben Gamari at 2020-04-26T18:43:13-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 1 changed file: - rts/linker/PEi386.c Changes: ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/274ec83f7464b84e318069cc26933c9bbd30abad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/274ec83f7464b84e318069cc26933c9bbd30abad You're receiving 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 27 00:15:25 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 26 Apr 2020 20:15:25 -0400 Subject: [Git][ghc/ghc][wip/T18103] Define a Quote IO instance Message-ID: <5ea6241dd317_616787c09cc7299574@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18103 at Glasgow Haskell Compiler / GHC Commits: d7d3f74a by Ryan Scott at 2020-04-26T20:13:48-04:00 Define a Quote IO instance Fixes #18103. - - - - - 4 changed files: - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/quotes/T18103.hs - testsuite/tests/quotes/TH_localname.stderr - testsuite/tests/quotes/all.T Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -122,8 +122,7 @@ class (MonadIO m, MonadFail m) => Quasi m where ----------------------------------------------------- instance Quasi IO where - qNewName s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x)) - ; pure (mkNameU s n) } + qNewName = newNameIO qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) @@ -150,6 +149,13 @@ instance Quasi IO where qIsExtEnabled _ = badIO "isExtEnabled" qExtsEnabled = badIO "extsEnabled" +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" } ===================================== testsuite/tests/quotes/T18103.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskellQuotes #-} +module T18103 where + +import Language.Haskell.TH + +ex :: IO [Dec] +ex = [d| foo x = x |] ===================================== testsuite/tests/quotes/TH_localname.stderr ===================================== @@ -7,8 +7,10 @@ TH_localname.hs:3:11: error: x :: t0 -> m0 Language.Haskell.TH.Syntax.Exp (bound at TH_localname.hs:3:1) Probable fix: use a type annotation to specify what ‘m0’ should be. - These potential instance exist: - one instance involving out-of-scope types + These potential instances exist: + instance Language.Haskell.TH.Syntax.Quote IO + -- Defined in ‘Language.Haskell.TH.Syntax’ + ...plus one instance involving out-of-scope types (use -fprint-potential-instances to see them all) • In the expression: [| y |] ===================================== testsuite/tests/quotes/all.T ===================================== @@ -17,6 +17,7 @@ test('T9824', normal, compile, ['-v0']) test('T10384', normal, compile_fail, ['']) test('T16384', req_th, compile, ['']) test('T17857', normal, compile, ['']) +test('T18103', normal, compile, ['']) test('TH_tf2', normal, compile, ['-v0']) test('TH_ppr1', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7d3f74ab36f691d6580ec40a2265de160fec0cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7d3f74ab36f691d6580ec40a2265de160fec0cd You're receiving 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 27 07:22:40 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 03:22:40 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Fix DataConWrapperCpr and accept other test outputs Message-ID: <5ea68840e3c9f_61673f81cd4c695c7313182@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: edabf4c9 by Sebastian Graf at 2020-04-27T09:22:35+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - 7 changed files: - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr Changes: ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -206,8 +206,8 @@ whnfTermCpr = Cpr Terminates Top divergeCpr :: Cpr divergeCpr = Cpr MightDiverge Bot -conCpr :: TerminationFlag -> ConTag -> [Cpr] -> Cpr -conCpr tf t fs = Cpr tf (Levitate (Con t fs)) +conCpr :: ConTag -> [Cpr] -> Cpr +conCpr t fs = Cpr Terminates (Levitate (Con t fs)) -- | Forget encoded CPR info, but keep termination info. forgetCpr :: Cpr -> Termination @@ -299,13 +299,13 @@ extractArgCprAndTermination = map go go _ = topCpr conCprType :: ConTag -> [CprType] -> CprType -conCprType con_tag args = CprType 0 (conCpr Terminates con_tag cprs) +conCprType con_tag args = CprType 0 (conCpr con_tag cprs) where cprs = extractArgCprAndTermination args markConCprType :: DataCon -> CprType -> CprType markConCprType dc _ty@(CprType n cpr) - = ASSERT2( n == 0, ppr _ty ) CprType 0 (conCpr Terminates con_tag fields) + = ASSERT2( n == 0, ppr _ty ) CprType 0 (conCpr con_tag fields) where con_tag = dataConTag dc wkr_arity = dataConRepArity dc ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -611,6 +611,7 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con `setInlinePragInfo` wrap_prag `setUnfoldingInfo` wrap_unf `setStrictnessInfo` wrap_sig + `setCprInfo` mkCprSig wrap_arity wrap_cpr -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane @@ -627,6 +628,8 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con mk_dmd str | isBanged str = evalDmd | otherwise = topDmd + wrap_cpr = conCpr (dataConTag data_con) (replicate wrap_arity topCpr) + wrap_prag = dataConWrapperInlinePragma `setInlinePragmaActivation` activeDuringFinal -- See Note [Activation for data constructor wrappers] ===================================== testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr ===================================== @@ -7,6 +7,6 @@ DataConWrapperCpr.$tc'Foo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), DataConWrapperCpr.$tcFoo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)) DataConWrapperCpr.$trModule: #c1(#c1(#), #c1(#)) -DataConWrapperCpr.foo: #c1(#) +DataConWrapperCpr.foo: #c1(*) ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -7,6 +7,7 @@ Result size of Tidy Core T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, + Cpr=#c1(), Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=False) @@ -16,7 +17,7 @@ T2431.$WRefl -- RHS size: {terms: 4, types: 8, coercions: 0, joins: 0/0} absurd :: forall a. (Int :~: Bool) -> a -[GblId, Arity=1, Str=b, Cpr=#b, Unf=OtherCon []] +[GblId, Arity=1, Str=b, Cpr=*b, Unf=OtherCon []] absurd = \ (@a) (x :: Int :~: Bool) -> case x of { } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -7,7 +7,7 @@ Rec { -- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. GHC.Prim.Void# -> a -[GblId, Arity=1, Str=b, Cpr=#b, Unf=OtherCon []] +[GblId, Arity=1, Str=b, Cpr=*b, Unf=OtherCon []] T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.void# end Rec } @@ -16,7 +16,7 @@ f [InlPrag=NOUSERINLINE[0]] :: forall a. Int -> a [GblId, Arity=1, Str=b, - Cpr=#b, + Cpr=*b, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) @@ -66,7 +66,7 @@ T13143.$trModule -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} lvl :: Int -[GblId, Str=b, Cpr=#b] +[GblId, Str=b, Cpr=*b] lvl = T13143.$wf @Int GHC.Prim.void# Rec { ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -51,7 +51,7 @@ lvl = "spec-inline.hs:(19,5)-(29,25)|function go"# -- RHS size: {terms: 2, types: 2, coercions: 0, joins: 0/0} Roman.foo3 :: Int -[GblId, Str=b, Cpr=#b] +[GblId, Str=b, Cpr=*b] Roman.foo3 = Control.Exception.Base.patError @'GHC.Types.LiftedRep @Int lvl ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -25,7 +25,7 @@ DmdAnalGADTs.$tc'B: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, DmdAnalGADTs.$tcD: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))) DmdAnalGADTs.$trModule: #c1(#c1(#), #c1(#)) -DmdAnalGADTs.diverges: *(#..) +DmdAnalGADTs.diverges: *b DmdAnalGADTs.f: * DmdAnalGADTs.f': #c1(#) DmdAnalGADTs.g: * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edabf4c94323b2d79aeec8fe89897a97309beb9e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edabf4c94323b2d79aeec8fe89897a97309beb9e You're receiving 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 27 07:23:22 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 03:23:22 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 21 commits: Create di_scoped_tvs for associated data family instances properly Message-ID: <5ea6886a1926f_61673f819b417d1c7314016@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - f09cacb6 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Nested CPR - - - - - bfc8e57d by Sebastian Graf at 2020-04-27T09:23:08+02:00 Move tests from stranal to cpranal - - - - - 9450af7a by Sebastian Graf at 2020-04-27T09:23:08+02:00 Accept FacState - - - - - f6ac3513 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Factor Cpr and Termination into a joint lattice As a result, we don't even have to export Termination from Cpr. Neat! Also I realised there is a simpler and more sound way to generate and unleash CPR signatures. - - - - - 3e47f58e by Sebastian Graf at 2020-04-27T09:23:08+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - bfefb359 by Sebastian Graf at 2020-04-27T09:23:08+02:00 stuff - - - - - 4701dd98 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Debug output - - - - - 2e0ed799 by Sebastian Graf at 2020-04-27T09:23:08+02:00 A slew of testsuite changes - - - - - 35caa8ed by Sebastian Graf at 2020-04-27T09:23:08+02:00 Fix T1600 - - - - - 5db8fc51 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - bf44d5e4 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Fix primop termination - - - - - efccbbe2 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Test for DataCon wrapper CPR - - - - - b60a7ec0 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Fix CPR of bottoming functions/primops - - - - - 74b81986 by Sebastian Graf at 2020-04-27T09:23:08+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/edabf4c94323b2d79aeec8fe89897a97309beb9e...74b819863911f0db4ee0d7ce8fb00c163ef3390a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/edabf4c94323b2d79aeec8fe89897a97309beb9e...74b819863911f0db4ee0d7ce8fb00c163ef3390a You're receiving 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 27 09:04:39 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 05:04:39 -0400 Subject: [Git][ghc/ghc][wip/T18092] Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Message-ID: <5ea6a02758df0_6167116e29d473297c5@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18092 at Glasgow Haskell Compiler / GHC Commits: d2ca9e52 by Sebastian Graf at 2020-04-27T10:53:58+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. As a result, `decodeDoubleInteger` no longer needs to be known-key. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Part of #18092. This improves the 32-bit `realToFrac`/`toRational`: Metric Decrease: T10359 - - - - - 3 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - libraries/integer-gmp/src/GHC/Integer/Type.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -381,7 +381,6 @@ basicKnownKeyNames quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName, @@ -1125,7 +1124,6 @@ integerTyConName, mkIntegerName, integerSDataConName, quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName :: Name @@ -1163,7 +1161,6 @@ floatFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "floatFromInteger") doubleFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "doubleFromInteger") doubleFromIntegerIdKey encodeFloatIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeFloatInteger") encodeFloatIntegerIdKey encodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeDoubleInteger") encodeDoubleIntegerIdKey -decodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "decodeDoubleInteger") decodeDoubleIntegerIdKey gcdIntegerName = varQual gHC_INTEGER_TYPE (fsLit "gcdInteger") gcdIntegerIdKey lcmIntegerName = varQual gHC_INTEGER_TYPE (fsLit "lcmInteger") lcmIntegerIdKey andIntegerName = varQual gHC_INTEGER_TYPE (fsLit "andInteger") andIntegerIdKey @@ -2149,7 +2146,6 @@ mkIntegerIdKey, smallIntegerIdKey, wordToIntegerIdKey, quotIntegerIdKey, remIntegerIdKey, divIntegerIdKey, modIntegerIdKey, floatFromIntegerIdKey, doubleFromIntegerIdKey, encodeFloatIntegerIdKey, encodeDoubleIntegerIdKey, - decodeDoubleIntegerIdKey, gcdIntegerIdKey, lcmIntegerIdKey, andIntegerIdKey, orIntegerIdKey, xorIntegerIdKey, complementIntegerIdKey, shiftLIntegerIdKey, shiftRIntegerIdKey :: Unique @@ -2193,7 +2189,8 @@ shiftRIntegerIdKey = mkPreludeMiscIdUnique 96 wordToIntegerIdKey = mkPreludeMiscIdUnique 97 word64ToIntegerIdKey = mkPreludeMiscIdUnique 98 int64ToIntegerIdKey = mkPreludeMiscIdUnique 99 -decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 +-- This one is "free" +-- decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -13,8 +13,7 @@ ToDo: -} {-# LANGUAGE CPP, RankNTypes, PatternSynonyms, ViewPatterns, RecordWildCards, - DeriveFunctor #-} -{-# LANGUAGE LambdaCase #-} + DeriveFunctor, LambdaCase, TypeApplications #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.ConstantFold @@ -249,18 +248,19 @@ primOpRules nm = \case , inversePrimOp FloatNegOp ] -- Double - DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) - , identity zerod ] - DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) - , rightIdentity zerod ] - DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) - , identity oned - , strengthReduction twod DoubleAddOp ] + DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) + , identity zerod ] + DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) + , rightIdentity zerod ] + DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) + , identity oned + , strengthReduction twod DoubleAddOp ] -- zeroElem zerod doesn't hold because of NaN - DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) - , rightIdentity oned ] - DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp - , inversePrimOp DoubleNegOp ] + DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) + , rightIdentity oned ] + DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp + , inversePrimOp DoubleNegOp ] + DoubleDecode_Int64Op -> mkPrimOpRule nm 1 [ unaryLit doubleDecodeOp ] -- Relational operators @@ -510,6 +510,22 @@ doubleOp2 op env (LitDouble f1) (LitDouble f2) = Just (mkDoubleVal env (f1 `op` f2)) doubleOp2 _ _ _ _ = Nothing +-------------------------- +doubleDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr +doubleDecodeOp env (LitDouble ((decodeFloat . fromRational @Double) -> (m, e))) + = Just $ mkCoreUbxTup [iNT64Ty, intPrimTy] + [ Lit (mkLitINT64 (roPlatform env) (toInteger m)) + , mkIntVal platform (toInteger e) ] + where + platform = roPlatform env + (iNT64Ty, mkLitINT64) + | platformWordSizeInBits platform < 64 + = (int64PrimTy, mkLitInt64Wrap) + | otherwise + = (intPrimTy , mkLitIntWrap) +doubleDecodeOp _ _ + = Nothing + -------------------------- {- Note [The litEq rule: converting equality to case] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1317,7 +1333,6 @@ builtinIntegerRules = rule_encodeFloat "encodeFloatInteger" encodeFloatIntegerName mkFloatLitFloat, rule_convert "floatFromInteger" floatFromIntegerName (\_ -> mkFloatLitFloat), rule_encodeFloat "encodeDoubleInteger" encodeDoubleIntegerName mkDoubleLitDouble, - rule_decodeDouble "decodeDoubleInteger" decodeDoubleIntegerName, rule_convert "doubleFromInteger" doubleFromIntegerName (\_ -> mkDoubleLitDouble), rule_rationalTo "rationalToFloat" rationalToFloatName mkFloatExpr, rule_rationalTo "rationalToDouble" rationalToDoubleName mkDoubleExpr, @@ -1390,9 +1405,6 @@ builtinIntegerRules = rule_encodeFloat str name op = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 2, ru_try = match_Integer_Int_encodeFloat op } - rule_decodeDouble str name - = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, - ru_try = match_decodeDouble } rule_XToIntegerToX str name toIntegerName = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, ru_try = match_XToIntegerToX toIntegerName } @@ -1747,22 +1759,6 @@ match_rationalTo mkLit _ id_unf _ [xl, yl] = Just (mkLit (fromRational (x % y))) match_rationalTo _ _ _ _ _ = Nothing -match_decodeDouble :: RuleFun -match_decodeDouble env id_unf fn [xl] - | Just (LitDouble x) <- exprIsLiteral_maybe id_unf xl - = case splitFunTy_maybe (idType fn) of - Just (_, res) - | Just [_lev1, _lev2, integerTy, intHashTy] <- tyConAppArgs_maybe res - -> case decodeFloat (fromRational x :: Double) of - (y, z) -> - Just $ mkCoreUbxTup [integerTy, intHashTy] - [Lit (mkLitInteger y integerTy), - Lit (mkLitInt (roPlatform env) (toInteger z))] - _ -> - pprPanic "match_decodeDouble: Id has the wrong type" - (ppr fn <+> dcolon <+> ppr (idType fn)) -match_decodeDouble _ _ _ _ = Nothing - match_XToIntegerToX :: Name -> RuleFun match_XToIntegerToX n _ _ _ [App (Var x) y] | idName x == n ===================================== libraries/integer-gmp/src/GHC/Integer/Type.hs ===================================== @@ -1618,7 +1618,6 @@ foreign import ccall unsafe "integer_gmp_invert" -- Conversions to/from floating point decodeDoubleInteger :: Double# -> (# Integer, Int# #) --- decodeDoubleInteger 0.0## = (# S# 0#, 0# #) #if WORD_SIZE_IN_BITS == 64 decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# S# m#, e# #) @@ -1626,7 +1625,10 @@ decodeDoubleInteger x = case decodeDouble_Int64# x of decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# int64ToInteger m#, e# #) #endif -{-# CONSTANT_FOLDED decodeDoubleInteger #-} +-- Rather than constant-folding `decodeDoubleInteger`, we have constant-folding +-- RULEs for the `decodeDouble_Int64#` PrimOp. Hence we inline this function. +-- As a bonus, inlining might eliminate the S# box! +{-# INLINE decodeDoubleInteger #-} -- provided by GHC's RTS foreign import ccall unsafe "__int_encodeDouble" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2ca9e52f24b4eb0178b0a573672ecfe065c1ee1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2ca9e52f24b4eb0178b0a573672ecfe065c1ee1 You're receiving 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 27 09:21:20 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 05:21:20 -0400 Subject: [Git][ghc/ghc][wip/T18092] Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Message-ID: <5ea6a410153a8_616787c09cc734221@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18092 at Glasgow Haskell Compiler / GHC Commits: b0814369 by Sebastian Graf at 2020-04-27T11:20:16+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. As a result, `decodeDoubleInteger` no longer needs to be known-key. While doing so, I realised that we don't constant-fold `decodeFloat_Int#` either, so I also added a RULE for it. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Part of #18092. This improves the 32-bit `realToFrac`/`toRational`: Metric Decrease: T10359 - - - - - 3 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - libraries/integer-gmp/src/GHC/Integer/Type.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -381,7 +381,6 @@ basicKnownKeyNames quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName, @@ -1125,7 +1124,6 @@ integerTyConName, mkIntegerName, integerSDataConName, quotIntegerName, remIntegerName, divIntegerName, modIntegerName, floatFromIntegerName, doubleFromIntegerName, encodeFloatIntegerName, encodeDoubleIntegerName, - decodeDoubleIntegerName, gcdIntegerName, lcmIntegerName, andIntegerName, orIntegerName, xorIntegerName, complementIntegerName, shiftLIntegerName, shiftRIntegerName, bitIntegerName :: Name @@ -1163,7 +1161,6 @@ floatFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "floatFromInteger") doubleFromIntegerName = varQual gHC_INTEGER_TYPE (fsLit "doubleFromInteger") doubleFromIntegerIdKey encodeFloatIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeFloatInteger") encodeFloatIntegerIdKey encodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "encodeDoubleInteger") encodeDoubleIntegerIdKey -decodeDoubleIntegerName = varQual gHC_INTEGER_TYPE (fsLit "decodeDoubleInteger") decodeDoubleIntegerIdKey gcdIntegerName = varQual gHC_INTEGER_TYPE (fsLit "gcdInteger") gcdIntegerIdKey lcmIntegerName = varQual gHC_INTEGER_TYPE (fsLit "lcmInteger") lcmIntegerIdKey andIntegerName = varQual gHC_INTEGER_TYPE (fsLit "andInteger") andIntegerIdKey @@ -2149,7 +2146,6 @@ mkIntegerIdKey, smallIntegerIdKey, wordToIntegerIdKey, quotIntegerIdKey, remIntegerIdKey, divIntegerIdKey, modIntegerIdKey, floatFromIntegerIdKey, doubleFromIntegerIdKey, encodeFloatIntegerIdKey, encodeDoubleIntegerIdKey, - decodeDoubleIntegerIdKey, gcdIntegerIdKey, lcmIntegerIdKey, andIntegerIdKey, orIntegerIdKey, xorIntegerIdKey, complementIntegerIdKey, shiftLIntegerIdKey, shiftRIntegerIdKey :: Unique @@ -2193,7 +2189,8 @@ shiftRIntegerIdKey = mkPreludeMiscIdUnique 96 wordToIntegerIdKey = mkPreludeMiscIdUnique 97 word64ToIntegerIdKey = mkPreludeMiscIdUnique 98 int64ToIntegerIdKey = mkPreludeMiscIdUnique 99 -decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 +-- This one is "free" +-- decodeDoubleIntegerIdKey = mkPreludeMiscIdUnique 100 rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -13,8 +13,7 @@ ToDo: -} {-# LANGUAGE CPP, RankNTypes, PatternSynonyms, ViewPatterns, RecordWildCards, - DeriveFunctor #-} -{-# LANGUAGE LambdaCase #-} + DeriveFunctor, LambdaCase, TypeApplications #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.ConstantFold @@ -235,32 +234,34 @@ primOpRules nm = \case Double2FloatOp -> mkPrimOpRule nm 1 [ liftLit double2FloatLit ] -- Float - FloatAddOp -> mkPrimOpRule nm 2 [ binaryLit (floatOp2 (+)) - , identity zerof ] - FloatSubOp -> mkPrimOpRule nm 2 [ binaryLit (floatOp2 (-)) - , rightIdentity zerof ] - FloatMulOp -> mkPrimOpRule nm 2 [ binaryLit (floatOp2 (*)) - , identity onef - , strengthReduction twof FloatAddOp ] + FloatAddOp -> mkPrimOpRule nm 2 [ binaryLit (floatOp2 (+)) + , identity zerof ] + FloatSubOp -> mkPrimOpRule nm 2 [ binaryLit (floatOp2 (-)) + , rightIdentity zerof ] + FloatMulOp -> mkPrimOpRule nm 2 [ binaryLit (floatOp2 (*)) + , identity onef + , strengthReduction twof FloatAddOp ] -- zeroElem zerof doesn't hold because of NaN - FloatDivOp -> mkPrimOpRule nm 2 [ guardFloatDiv >> binaryLit (floatOp2 (/)) - , rightIdentity onef ] - FloatNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp - , inversePrimOp FloatNegOp ] + FloatDivOp -> mkPrimOpRule nm 2 [ guardFloatDiv >> binaryLit (floatOp2 (/)) + , rightIdentity onef ] + FloatNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp + , inversePrimOp FloatNegOp ] + FloatDecode_IntOp -> mkPrimOpRule nm 1 [ unaryLit floatDecodeOp ] -- Double - DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) - , identity zerod ] - DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) - , rightIdentity zerod ] - DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) - , identity oned - , strengthReduction twod DoubleAddOp ] + DoubleAddOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (+)) + , identity zerod ] + DoubleSubOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (-)) + , rightIdentity zerod ] + DoubleMulOp -> mkPrimOpRule nm 2 [ binaryLit (doubleOp2 (*)) + , identity oned + , strengthReduction twod DoubleAddOp ] -- zeroElem zerod doesn't hold because of NaN - DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) - , rightIdentity oned ] - DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp - , inversePrimOp DoubleNegOp ] + DoubleDivOp -> mkPrimOpRule nm 2 [ guardDoubleDiv >> binaryLit (doubleOp2 (/)) + , rightIdentity oned ] + DoubleNegOp -> mkPrimOpRule nm 1 [ unaryLit negOp + , inversePrimOp DoubleNegOp ] + DoubleDecode_Int64Op -> mkPrimOpRule nm 1 [ unaryLit doubleDecodeOp ] -- Relational operators @@ -502,6 +503,15 @@ floatOp2 op env (LitFloat f1) (LitFloat f2) = Just (mkFloatVal env (f1 `op` f2)) floatOp2 _ _ _ _ = Nothing +-------------------------- +floatDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr +floatDecodeOp env (LitFloat ((decodeFloat . fromRational @Float) -> (m, e))) + = Just $ mkCoreUbxTup [intPrimTy, intPrimTy] + [ mkIntVal (roPlatform env) (toInteger m) + , mkIntVal (roPlatform env) (toInteger e) ] +floatDecodeOp _ _ + = Nothing + -------------------------- doubleOp2 :: (Rational -> Rational -> Rational) -> RuleOpts -> Literal -> Literal @@ -510,6 +520,22 @@ doubleOp2 op env (LitDouble f1) (LitDouble f2) = Just (mkDoubleVal env (f1 `op` f2)) doubleOp2 _ _ _ _ = Nothing +-------------------------- +doubleDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr +doubleDecodeOp env (LitDouble ((decodeFloat . fromRational @Double) -> (m, e))) + = Just $ mkCoreUbxTup [iNT64Ty, intPrimTy] + [ Lit (mkLitINT64 (roPlatform env) (toInteger m)) + , mkIntVal platform (toInteger e) ] + where + platform = roPlatform env + (iNT64Ty, mkLitINT64) + | platformWordSizeInBits platform < 64 + = (int64PrimTy, mkLitInt64Wrap) + | otherwise + = (intPrimTy , mkLitIntWrap) +doubleDecodeOp _ _ + = Nothing + -------------------------- {- Note [The litEq rule: converting equality to case] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1317,7 +1343,6 @@ builtinIntegerRules = rule_encodeFloat "encodeFloatInteger" encodeFloatIntegerName mkFloatLitFloat, rule_convert "floatFromInteger" floatFromIntegerName (\_ -> mkFloatLitFloat), rule_encodeFloat "encodeDoubleInteger" encodeDoubleIntegerName mkDoubleLitDouble, - rule_decodeDouble "decodeDoubleInteger" decodeDoubleIntegerName, rule_convert "doubleFromInteger" doubleFromIntegerName (\_ -> mkDoubleLitDouble), rule_rationalTo "rationalToFloat" rationalToFloatName mkFloatExpr, rule_rationalTo "rationalToDouble" rationalToDoubleName mkDoubleExpr, @@ -1390,9 +1415,6 @@ builtinIntegerRules = rule_encodeFloat str name op = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 2, ru_try = match_Integer_Int_encodeFloat op } - rule_decodeDouble str name - = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, - ru_try = match_decodeDouble } rule_XToIntegerToX str name toIntegerName = BuiltinRule { ru_name = fsLit str, ru_fn = name, ru_nargs = 1, ru_try = match_XToIntegerToX toIntegerName } @@ -1747,22 +1769,6 @@ match_rationalTo mkLit _ id_unf _ [xl, yl] = Just (mkLit (fromRational (x % y))) match_rationalTo _ _ _ _ _ = Nothing -match_decodeDouble :: RuleFun -match_decodeDouble env id_unf fn [xl] - | Just (LitDouble x) <- exprIsLiteral_maybe id_unf xl - = case splitFunTy_maybe (idType fn) of - Just (_, res) - | Just [_lev1, _lev2, integerTy, intHashTy] <- tyConAppArgs_maybe res - -> case decodeFloat (fromRational x :: Double) of - (y, z) -> - Just $ mkCoreUbxTup [integerTy, intHashTy] - [Lit (mkLitInteger y integerTy), - Lit (mkLitInt (roPlatform env) (toInteger z))] - _ -> - pprPanic "match_decodeDouble: Id has the wrong type" - (ppr fn <+> dcolon <+> ppr (idType fn)) -match_decodeDouble _ _ _ _ = Nothing - match_XToIntegerToX :: Name -> RuleFun match_XToIntegerToX n _ _ _ [App (Var x) y] | idName x == n ===================================== libraries/integer-gmp/src/GHC/Integer/Type.hs ===================================== @@ -1618,7 +1618,6 @@ foreign import ccall unsafe "integer_gmp_invert" -- Conversions to/from floating point decodeDoubleInteger :: Double# -> (# Integer, Int# #) --- decodeDoubleInteger 0.0## = (# S# 0#, 0# #) #if WORD_SIZE_IN_BITS == 64 decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# S# m#, e# #) @@ -1626,7 +1625,10 @@ decodeDoubleInteger x = case decodeDouble_Int64# x of decodeDoubleInteger x = case decodeDouble_Int64# x of (# m#, e# #) -> (# int64ToInteger m#, e# #) #endif -{-# CONSTANT_FOLDED decodeDoubleInteger #-} +-- Rather than constant-folding `decodeDoubleInteger`, we have constant-folding +-- RULEs for the `decodeDouble_Int64#` PrimOp. Hence we inline this function. +-- As a bonus, inlining might eliminate the S# box! +{-# INLINE decodeDoubleInteger #-} -- provided by GHC's RTS foreign import ccall unsafe "__int_encodeDouble" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b08143695d1e38c458c3bc98a591420a653cb7cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b08143695d1e38c458c3bc98a591420a653cb7cb You're receiving 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 27 09:39:40 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 05:39:40 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Fix DataConWrapperCpr and accept other test outputs Message-ID: <5ea6a85ceafdb_6167122e22ac734689@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 9acac76a by Sebastian Graf at 2020-04-27T11:39:31+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - 7 changed files: - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr Changes: ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -206,8 +206,8 @@ whnfTermCpr = Cpr Terminates Top divergeCpr :: Cpr divergeCpr = Cpr MightDiverge Bot -conCpr :: TerminationFlag -> ConTag -> [Cpr] -> Cpr -conCpr tf t fs = Cpr tf (Levitate (Con t fs)) +conCpr :: ConTag -> [Cpr] -> Cpr +conCpr t fs = Cpr Terminates (Levitate (Con t fs)) -- | Forget encoded CPR info, but keep termination info. forgetCpr :: Cpr -> Termination @@ -299,13 +299,13 @@ extractArgCprAndTermination = map go go _ = topCpr conCprType :: ConTag -> [CprType] -> CprType -conCprType con_tag args = CprType 0 (conCpr Terminates con_tag cprs) +conCprType con_tag args = CprType 0 (conCpr con_tag cprs) where cprs = extractArgCprAndTermination args markConCprType :: DataCon -> CprType -> CprType markConCprType dc _ty@(CprType n cpr) - = ASSERT2( n == 0, ppr _ty ) CprType 0 (conCpr Terminates con_tag fields) + = ASSERT2( n == 0, ppr _ty ) CprType 0 (conCpr con_tag fields) where con_tag = dataConTag dc wkr_arity = dataConRepArity dc ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -611,6 +611,7 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con `setInlinePragInfo` wrap_prag `setUnfoldingInfo` wrap_unf `setStrictnessInfo` wrap_sig + `setCprInfo` mkCprSig wrap_arity wrap_cpr -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane @@ -627,6 +628,8 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con mk_dmd str | isBanged str = evalDmd | otherwise = topDmd + wrap_cpr = conCpr (dataConTag data_con) (replicate wkr_arity topCpr) + wrap_prag = dataConWrapperInlinePragma `setInlinePragmaActivation` activeDuringFinal -- See Note [Activation for data constructor wrappers] @@ -671,6 +674,7 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con -- The wrap_args are the arguments *other than* the eq_spec -- Because we are going to apply the eq_spec args manually in the -- wrapper + wkr_arity = dataConRepArity data_con new_tycon = isNewTyCon tycon arg_ibangs ===================================== testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr ===================================== @@ -7,6 +7,6 @@ DataConWrapperCpr.$tc'Foo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), DataConWrapperCpr.$tcFoo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)) DataConWrapperCpr.$trModule: #c1(#c1(#), #c1(#)) -DataConWrapperCpr.foo: #c1(#) +DataConWrapperCpr.foo: #c1(*) ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -7,6 +7,7 @@ Result size of Tidy Core T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, + Cpr=#c1(), Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=False) @@ -16,7 +17,7 @@ T2431.$WRefl -- RHS size: {terms: 4, types: 8, coercions: 0, joins: 0/0} absurd :: forall a. (Int :~: Bool) -> a -[GblId, Arity=1, Str=b, Cpr=#b, Unf=OtherCon []] +[GblId, Arity=1, Str=b, Cpr=*b, Unf=OtherCon []] absurd = \ (@a) (x :: Int :~: Bool) -> case x of { } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -7,7 +7,7 @@ Rec { -- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. GHC.Prim.Void# -> a -[GblId, Arity=1, Str=b, Cpr=#b, Unf=OtherCon []] +[GblId, Arity=1, Str=b, Cpr=*b, Unf=OtherCon []] T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.void# end Rec } @@ -16,7 +16,7 @@ f [InlPrag=NOUSERINLINE[0]] :: forall a. Int -> a [GblId, Arity=1, Str=b, - Cpr=#b, + Cpr=*b, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) @@ -66,7 +66,7 @@ T13143.$trModule -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} lvl :: Int -[GblId, Str=b, Cpr=#b] +[GblId, Str=b, Cpr=*b] lvl = T13143.$wf @Int GHC.Prim.void# Rec { ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -51,7 +51,7 @@ lvl = "spec-inline.hs:(19,5)-(29,25)|function go"# -- RHS size: {terms: 2, types: 2, coercions: 0, joins: 0/0} Roman.foo3 :: Int -[GblId, Str=b, Cpr=#b] +[GblId, Str=b, Cpr=*b] Roman.foo3 = Control.Exception.Base.patError @'GHC.Types.LiftedRep @Int lvl ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -25,7 +25,7 @@ DmdAnalGADTs.$tc'B: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, DmdAnalGADTs.$tcD: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))) DmdAnalGADTs.$trModule: #c1(#c1(#), #c1(#)) -DmdAnalGADTs.diverges: *(#..) +DmdAnalGADTs.diverges: *b DmdAnalGADTs.f: * DmdAnalGADTs.f': #c1(#) DmdAnalGADTs.g: * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9acac76afc7ab639d60742c4a650de62a3be8860 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9acac76afc7ab639d60742c4a650de62a3be8860 You're receiving 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 27 14:32:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 27 Apr 2020 10:32:30 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5ea6ecfe4c3d7_6167116e29d47419619@gitlab.haskell.org.mail> Ben Gamari pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 30 changed files: - 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/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ac29c885fba7ed69de83a597cdbd03696c9ed13...22bf5c738e0339fa12940414d6448896c6733808 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ac29c885fba7ed69de83a597cdbd03696c9ed13...22bf5c738e0339fa12940414d6448896c6733808 You're receiving 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 27 15:34:34 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 27 Apr 2020 11:34:34 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: TH: fix Show/Eq/Ord instances for Bytes (#16457) Message-ID: <5ea6fb8a5ad8d_61673f819b417d1c7438411@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cb4dbc0c by Sylvain Henry at 2020-04-27T11:34:24-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - e74b9ee2 by Alp Mestanogullari at 2020-04-27T11:34:29-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 6 changed files: - hadrian/src/Builder.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/th/TH_BytesShowEqOrd.hs - + testsuite/tests/th/TH_BytesShowEqOrd.stdout - testsuite/tests/th/all.T Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE InstanceSigs, TypeOperators #-} module Builder ( -- * Data types ArMode (..), CcMode (..), ConfigurationInfo (..), GhcMode (..), @@ -14,7 +14,9 @@ module Builder ( applyPatch ) where +import Control.Exception.Extra (Partial) import Development.Shake.Classes +import Development.Shake.Command import GHC.Generics import qualified Hadrian.Builder as H import Hadrian.Builder hiding (Builder) @@ -214,7 +216,7 @@ instance H.Builder Builder where needBuilder builder path <- H.builderPath builder need [path] - Stdout stdout <- cmd [path] ["--no-user-package-db", "field", input, "depends"] + Stdout stdout <- cmd' [path] ["--no-user-package-db", "field", input, "depends"] return stdout _ -> error $ "Builder " ++ show builder ++ " can not be asked!" @@ -231,7 +233,7 @@ instance H.Builder Builder where echo = EchoStdout (verbosity >= Loud) -- Capture stdout and write it to the output file. captureStdout = do - Stdout stdout <- cmd [path] buildArgs + Stdout stdout <- cmd' [path] buildArgs writeFileChanged output stdout case builder of Ar Pack _ -> do @@ -239,54 +241,54 @@ instance H.Builder Builder where if useTempFile then runAr path buildArgs else runArWithoutTempFile path buildArgs - Ar Unpack _ -> cmd echo [Cwd output] [path] buildArgs + Ar Unpack _ -> cmd' echo [Cwd output] [path] buildArgs - Autoreconf dir -> cmd echo [Cwd dir] ["sh", path] buildArgs + Autoreconf dir -> cmd' echo [Cwd dir] ["sh", path] buildArgs Configure dir -> do -- Inject /bin/bash into `libtool`, instead of /bin/sh, -- otherwise Windows breaks. TODO: Figure out why. bash <- bashPath let env = AddEnv "CONFIG_SHELL" bash - cmd echo env [Cwd dir] ["sh", path] buildOptions buildArgs + cmd' echo env [Cwd dir] ["sh", path] buildOptions buildArgs GenApply -> captureStdout GenPrimopCode -> do stdin <- readFile' input - Stdout stdout <- cmd (Stdin stdin) [path] buildArgs + Stdout stdout <- cmd' (Stdin stdin) [path] buildArgs writeFileChanged output stdout GhcPkg Copy _ -> do - Stdout pkgDesc <- cmd [path] + Stdout pkgDesc <- cmd' [path] [ "--expand-pkgroot" , "--no-user-package-db" , "describe" , input -- the package name ] - cmd (Stdin pkgDesc) [path] (buildArgs ++ ["-"]) + cmd' (Stdin pkgDesc) [path] (buildArgs ++ ["-"]) GhcPkg Unregister _ -> do - Exit _ <- cmd echo [path] (buildArgs ++ [input]) + Exit _ <- cmd' echo [path] (buildArgs ++ [input]) return () HsCpp -> captureStdout - Make dir -> cmd echo path ["-C", dir] buildArgs + Make dir -> cmd' echo path ["-C", dir] buildArgs Makeinfo -> do - cmd echo [path] "--no-split" [ "-o", output] [input] + cmd' echo [path] "--no-split" [ "-o", output] [input] Xelatex -> do - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] ["makeindex"] (input -<.> "idx") - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] ["makeindex"] (input -<.> "idx") + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs - Tar _ -> cmd buildOptions echo [path] buildArgs - _ -> cmd echo [path] buildArgs + Tar _ -> cmd' buildOptions echo [path] buildArgs + _ -> cmd' echo [path] buildArgs -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform @@ -366,4 +368,9 @@ applyPatch dir patch = do needBuilder Patch path <- builderPath Patch putBuild $ "| Apply patch " ++ file - quietly $ cmd [Cwd dir, FileStdin file] [path, "-p0"] + quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] + +-- | Wrapper for 'cmd' that makes sure we include both stdout and stderr in +-- Shake's output when any of our builder commands fail. +cmd' :: (Partial, CmdArguments args) => args :-> Action r +cmd' = cmd [WithStderr True, WithStdout True] ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -45,12 +45,15 @@ import GHC.Generics ( Generic ) import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), TYPE, RuntimeRep(..) ) 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 import Foreign.ForeignPtr +import Foreign.C.String +import Foreign.C.Types ----------------------------------------------------- -- @@ -1868,7 +1871,45 @@ data Bytes = Bytes -- , bytesInitialized :: Bool -- ^ False: only use `bytesSize` to allocate -- -- an uninitialized region } - deriving (Eq,Ord,Data,Generic,Show) + 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 @{}@ ===================================== libraries/template-haskell/changelog.md ===================================== @@ -10,6 +10,12 @@ and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. + * Fix Eq/Ord instances for `Bytes`: we were comparing pointers while we should + compare the actual bytes (#16457). + + * Fix Show instance for `Bytes`: we were showing the pointer value while we + want to show the contents (#16457). + ## 2.16.0.0 *TBA* * Add support for tuple sections. (#15843) The type signatures of `TupE` and ===================================== testsuite/tests/th/TH_BytesShowEqOrd.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} + +module Main where + +import Language.Haskell.TH.Lib +import GHC.Ptr +import Foreign.ForeignPtr + +main :: IO () +main = do + + let + !x = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"# + !y = "ABCDEabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"# + + p1 <- newForeignPtr_ (Ptr x) + p2 <- newForeignPtr_ (Ptr y) + + let + b1 = mkBytes p1 0 5 + b2 = mkBytes p1 10 5 + b3 = mkBytes p1 26 5 + b4 = mkBytes p2 5 5 + b5 = mkBytes p2 10 5 + + let myCmp a b = putStrLn $ "compare " ++ show a ++ " to " ++ show b ++ " => " ++ show (compare a b) + + putStr "same pointer, same offset, same bytes: " + myCmp b1 b1 + putStr "same pointer, different offset, same bytes: " + myCmp b1 b3 + putStr "same pointer, different offset, different bytes: " + myCmp b1 b2 + putStr "same pointer, different offset, different bytes: " + myCmp b2 b1 + putStr "different pointer, different offset, same bytes: " + myCmp b1 b4 + putStr "different pointer, different offset, different bytes: " + myCmp b1 b5 ===================================== testsuite/tests/th/TH_BytesShowEqOrd.stdout ===================================== @@ -0,0 +1,6 @@ +same pointer, same offset, same bytes: compare abcde to abcde => EQ +same pointer, different offset, same bytes: compare abcde to abcde => EQ +same pointer, different offset, different bytes: compare abcde to klmno => LT +same pointer, different offset, different bytes: compare klmno to abcde => GT +different pointer, different offset, same bytes: compare abcde to abcde => EQ +different pointer, different offset, different bytes: compare abcde to fghij => LT ===================================== testsuite/tests/th/all.T ===================================== @@ -504,3 +504,4 @@ test('T17688a', normal, compile, ['']) test('T17688b', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) +test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/22bf5c738e0339fa12940414d6448896c6733808...e74b9ee22e2523141a898cdddf27f0bad398cfb9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/22bf5c738e0339fa12940414d6448896c6733808...e74b9ee22e2523141a898cdddf27f0bad398cfb9 You're receiving 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 27 19:06:28 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 15:06:28 -0400 Subject: [Git][ghc/ghc][wip/T18049] PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info Message-ID: <5ea72d34dea32_61673f81cd4c695c74763b7@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18049 at Glasgow Haskell Compiler / GHC Commits: 521b1692 by Sebastian Graf at 2020-04-27T21:06:16+02:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` and `WpLet` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. Fixes #18049. - - - - - 6 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Tc/Types/Evidence.hs - + testsuite/tests/pmcheck/should_compile/T18049.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -33,7 +33,7 @@ import {-# SOURCE #-} GHC.HsToCore.Match ( matchWrapper ) import GHC.HsToCore.Monad import GHC.HsToCore.GuardedRHSs import GHC.HsToCore.Utils -import GHC.HsToCore.PmCheck ( needToRunPmCheck, addTyCsDs, checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Hs -- lots of things import GHC.Core -- lots of things @@ -145,12 +145,20 @@ dsHsBind dflags (VarBind { var_id = var else [] ; return (force_var, [core_bind]) } -dsHsBind dflags b@(FunBind { fun_id = L _ fun +dsHsBind dflags b@(FunBind { fun_id = L loc fun , fun_matches = matches , fun_ext = co_fn , fun_tick = tick }) - = do { (args, body) <- matchWrapper - (mkPrefixFunRhs (noLoc $ idName fun)) + = do { (args, body) <- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + -- FromSource might not be accurate (we don't have any + -- origin annotations for things in this module), but at + -- worst we do superfluous calls to the pattern match + -- oracle. + -- addTyCsDs: Add type evidence to the refinement type + -- predicate of the coverage checker + -- See Note [Type and Term Equality Propagation] in PmCheck + matchWrapper + (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body @@ -189,15 +197,7 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts , abs_exports = exports , abs_ev_binds = ev_binds , abs_binds = binds, abs_sig = has_sig }) - = do { ds_binds <- applyWhen (needToRunPmCheck dflags FromSource) - -- FromSource might not be accurate, but at worst - -- we do superfluous calls to the pattern match - -- oracle. - -- addTyCsDs: push type constraints deeper - -- for inner pattern match check - -- See Check, Note [Type and Term Equality Propagation] - (addTyCsDs (listToBag dicts)) - (dsLHsBinds binds) + = do { ds_binds <- addTyCsDs FromSource (listToBag dicts) (dsLHsBinds binds) ; ds_ev_binds <- dsTcEvBinds_s ev_binds @@ -206,7 +206,6 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind" - ----------------------- dsAbsBinds :: DynFlags -> [TyVar] -> [EvVar] -> [ABExport GhcTc] ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.HsToCore.ListComp import GHC.HsToCore.Utils import GHC.HsToCore.Arrows import GHC.HsToCore.Monad -import GHC.HsToCore.PmCheck ( checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Types.Name import GHC.Types.Name.Env import GHC.Core.FamInstEnv( topNormaliseType ) @@ -280,7 +280,13 @@ dsExpr hswrap@(XExpr (HsWrap co_fn e)) HsConLikeOut _ (RealDataCon dc) -> return $ varToCoreExpr (dataConWrapId dc) XExpr (HsWrap _ _) -> pprPanic "dsExpr: HsWrap inside HsWrap" (ppr hswrap) HsPar _ _ -> pprPanic "dsExpr: HsPar inside HsWrap" (ppr hswrap) - _ -> dsExpr e + _ -> -- Uncommenting the following line leads to a 300% + -- compile-time allocation regression in T3064, see + -- !3087. Unless we find a testcase that motivates this + -- change, I'm not willing to think of a complicated + -- work-around. + -- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + dsExpr e -- See Note [Detecting forced eta expansion] ; wrap' <- dsHsWrapper co_fn ; dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -14,7 +14,7 @@ Pattern Matching Coverage Checking. module GHC.HsToCore.PmCheck ( -- Checking and printing checkSingle, checkMatches, checkGuardMatches, - needToRunPmCheck, isMatchContextPmChecked, + isMatchContextPmChecked, -- See Note [Type and Term Equality Propagation] addTyCsDs, addScrutTmCs @@ -1041,10 +1041,14 @@ locallyExtendPmDelta ext k = getPmDeltas >>= ext >>= \deltas -> do then updPmDeltas deltas k else k --- | Add in-scope type constraints -addTyCsDs :: Bag EvVar -> DsM a -> DsM a -addTyCsDs ev_vars = - locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars)) +-- | Add in-scope type constraints if the coverage checker might run and then +-- run the given action. +addTyCsDs :: Origin -> Bag EvVar -> DsM a -> DsM a +addTyCsDs origin ev_vars m = do + dflags <- getDynFlags + applyWhen (needToRunPmCheck dflags origin) + (locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars))) + m -- | Add equalities for the scrutinee to the local 'DsM' environment when -- checking a case expression: ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -10,7 +10,7 @@ module GHC.Tc.Types.Evidence ( (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, - pprHsWrapper, + pprHsWrapper, hsWrapDictBinders, -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), @@ -370,6 +370,25 @@ isErasableHsWrapper = go go WpTyApp{} = True go WpLet{} = False +hsWrapDictBinders :: HsWrapper -> Bag DictId +-- Collects the given dict Ids, bound by the wrapper, +-- that scope over the "hole" in the wrapper +hsWrapDictBinders wrap = go wrap emptyBag + where + go WpHole acc = acc + go (w1 `WpCompose` w2) acc = go w1 (go w2 acc) + go (WpFun _ w2 _ _) acc = go w2 acc + go (WpCast {}) acc = acc + go (WpEvLam dict_id) acc = dict_id `consBag` acc + go (WpEvApp {}) acc = acc + go (WpTyLam {}) acc = acc + go (WpTyApp {}) acc = acc + go (WpLet binds) acc = go_binds binds `unionBags` acc + + go_binds (EvBinds bs) = mapBag eb_lhs bs + go_binds (TcEvBinds ebv) = pprPanic "hsWrapperDictBinds" (ppr ebv) + -- Should only be applied post zonking + collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, -- stopping as soon as you get to a non-lambda binder ===================================== testsuite/tests/pmcheck/should_compile/T18049.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +module Bug where + +import Data.Kind + +data SBool :: Bool -> Type where + SFalse :: SBool False + STrue :: SBool True + +f :: SBool b + -> (b ~ True => SBool b -> r) + -> (b ~ False => SBool b -> r) + -> r +f x t f = + case x of + SFalse -> f x + STrue -> t x + +g :: forall b. SBool b -> () +g x = f x + (\x' -> + case x' of + -- SFalse -> () + STrue -> ()) + (\_ -> ()) ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -118,6 +118,8 @@ test('T17977', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17977b', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T18049', normal, compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/521b1692a94ec4d127f9a30e55d131defa92db6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/521b1692a94ec4d127f9a30e55d131defa92db6c You're receiving 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 27 19:07:06 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 15:07:06 -0400 Subject: [Git][ghc/ghc][wip/T18049] 71 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5ea72d5a44890_61673f81cd4c695c7476768@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18049 at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - d533116a by Sebastian Graf at 2020-04-27T21:06:58+02:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` and `WpLet` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. Fixes #18049. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/521b1692a94ec4d127f9a30e55d131defa92db6c...d533116ac8c6bb75d1430f36ac11824f883d9e63 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/521b1692a94ec4d127f9a30e55d131defa92db6c...d533116ac8c6bb75d1430f36ac11824f883d9e63 You're receiving 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 27 19:16:23 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 27 Apr 2020 15:16:23 -0400 Subject: [Git][ghc/ghc][wip/T18049] PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info Message-ID: <5ea72f87db296_6167c5ce1b074786b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18049 at Glasgow Haskell Compiler / GHC Commits: d866e118 by Sebastian Graf at 2020-04-27T21:16:16+02:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` and `WpLet` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. Fixes #18049. - - - - - 6 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Tc/Types/Evidence.hs - + testsuite/tests/pmcheck/should_compile/T18049.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -33,7 +33,7 @@ import {-# SOURCE #-} GHC.HsToCore.Match ( matchWrapper ) import GHC.HsToCore.Monad import GHC.HsToCore.GuardedRHSs import GHC.HsToCore.Utils -import GHC.HsToCore.PmCheck ( needToRunPmCheck, addTyCsDs, checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Hs -- lots of things import GHC.Core -- lots of things @@ -145,12 +145,20 @@ dsHsBind dflags (VarBind { var_id = var else [] ; return (force_var, [core_bind]) } -dsHsBind dflags b@(FunBind { fun_id = L _ fun +dsHsBind dflags b@(FunBind { fun_id = L loc fun , fun_matches = matches , fun_ext = co_fn , fun_tick = tick }) - = do { (args, body) <- matchWrapper - (mkPrefixFunRhs (noLoc $ idName fun)) + = do { (args, body) <- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + -- FromSource might not be accurate (we don't have any + -- origin annotations for things in this module), but at + -- worst we do superfluous calls to the pattern match + -- oracle. + -- addTyCsDs: Add type evidence to the refinement type + -- predicate of the coverage checker + -- See Note [Type and Term Equality Propagation] in PmCheck + matchWrapper + (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body @@ -189,15 +197,7 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts , abs_exports = exports , abs_ev_binds = ev_binds , abs_binds = binds, abs_sig = has_sig }) - = do { ds_binds <- applyWhen (needToRunPmCheck dflags FromSource) - -- FromSource might not be accurate, but at worst - -- we do superfluous calls to the pattern match - -- oracle. - -- addTyCsDs: push type constraints deeper - -- for inner pattern match check - -- See Check, Note [Type and Term Equality Propagation] - (addTyCsDs (listToBag dicts)) - (dsLHsBinds binds) + = do { ds_binds <- addTyCsDs FromSource (listToBag dicts) (dsLHsBinds binds) ; ds_ev_binds <- dsTcEvBinds_s ev_binds @@ -206,7 +206,6 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind" - ----------------------- dsAbsBinds :: DynFlags -> [TyVar] -> [EvVar] -> [ABExport GhcTc] ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -280,7 +280,13 @@ dsExpr hswrap@(XExpr (HsWrap co_fn e)) HsConLikeOut _ (RealDataCon dc) -> return $ varToCoreExpr (dataConWrapId dc) XExpr (HsWrap _ _) -> pprPanic "dsExpr: HsWrap inside HsWrap" (ppr hswrap) HsPar _ _ -> pprPanic "dsExpr: HsPar inside HsWrap" (ppr hswrap) - _ -> dsExpr e + _ -> -- Uncommenting the following line leads to a 300% + -- compile-time allocation regression in T3064, see + -- !3087. Unless we find a testcase that motivates this + -- change, I'm not willing to think of a complicated + -- work-around. + -- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + dsExpr e -- See Note [Detecting forced eta expansion] ; wrap' <- dsHsWrapper co_fn ; dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -14,7 +14,7 @@ Pattern Matching Coverage Checking. module GHC.HsToCore.PmCheck ( -- Checking and printing checkSingle, checkMatches, checkGuardMatches, - needToRunPmCheck, isMatchContextPmChecked, + isMatchContextPmChecked, -- See Note [Type and Term Equality Propagation] addTyCsDs, addScrutTmCs @@ -1043,10 +1043,14 @@ locallyExtendPmDelta ext k = getPmDeltas >>= ext >>= \deltas -> do then updPmDeltas deltas k else k --- | Add in-scope type constraints -addTyCsDs :: Bag EvVar -> DsM a -> DsM a -addTyCsDs ev_vars = - locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars)) +-- | Add in-scope type constraints if the coverage checker might run and then +-- run the given action. +addTyCsDs :: Origin -> Bag EvVar -> DsM a -> DsM a +addTyCsDs origin ev_vars m = do + dflags <- getDynFlags + applyWhen (needToRunPmCheck dflags origin) + (locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars))) + m -- | Add equalities for the scrutinee to the local 'DsM' environment when -- checking a case expression: ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -10,7 +10,7 @@ module GHC.Tc.Types.Evidence ( (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, - pprHsWrapper, + pprHsWrapper, hsWrapDictBinders, -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), @@ -370,6 +370,25 @@ isErasableHsWrapper = go go WpTyApp{} = True go WpLet{} = False +hsWrapDictBinders :: HsWrapper -> Bag DictId +-- Collects the given dict Ids, bound by the wrapper, +-- that scope over the "hole" in the wrapper +hsWrapDictBinders wrap = go wrap emptyBag + where + go WpHole acc = acc + go (w1 `WpCompose` w2) acc = go w1 (go w2 acc) + go (WpFun _ w2 _ _) acc = go w2 acc + go (WpCast {}) acc = acc + go (WpEvLam dict_id) acc = dict_id `consBag` acc + go (WpEvApp {}) acc = acc + go (WpTyLam {}) acc = acc + go (WpTyApp {}) acc = acc + go (WpLet binds) acc = go_binds binds `unionBags` acc + + go_binds (EvBinds bs) = mapBag eb_lhs bs + go_binds (TcEvBinds ebv) = pprPanic "hsWrapperDictBinds" (ppr ebv) + -- Should only be applied post zonking + collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, -- stopping as soon as you get to a non-lambda binder ===================================== testsuite/tests/pmcheck/should_compile/T18049.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +module Bug where + +import Data.Kind + +data SBool :: Bool -> Type where + SFalse :: SBool False + STrue :: SBool True + +f :: SBool b + -> (b ~ True => SBool b -> r) + -> (b ~ False => SBool b -> r) + -> r +f x t f = + case x of + SFalse -> f x + STrue -> t x + +g :: forall b. SBool b -> () +g x = f x + (\x' -> + case x' of + -- SFalse -> () + STrue -> ()) + (\_ -> ()) ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -118,6 +118,8 @@ test('T17977', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17977b', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T18049', normal, compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d866e11829e223523d526e2bc998d6df22c36a2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d866e11829e223523d526e2bc998d6df22c36a2e You're receiving 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 27 19:38:19 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 27 Apr 2020 15:38:19 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 79 commits: testsuite: Move no_lint to the top level, tweak hie002 Message-ID: <5ea734ab9756e_6167120888bc74792c1@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 5ed95e3c by Ömer Sinan Ağacan at 2020-04-27T22:38:03+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/33f9a555bf9c968908124fc6c5143d9a758d6fb8...5ed95e3c7d59c800e1e607cc4905d4043c462ab9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/33f9a555bf9c968908124fc6c5143d9a758d6fb8...5ed95e3c7d59c800e1e607cc4905d4043c462ab9 You're receiving 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 27 20:03:07 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Mon, 27 Apr 2020 16:03:07 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5ea73a7b59447_61673f819b417d1c74805fd@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: f43a8474 by Ömer Sinan Ağacan at 2020-04-27T23:02:49+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -74,6 +76,8 @@ import GHC.Types.Demand ( isTopSig ) import GHC.Types.Cpr ( topCprSig ) import Data.Maybe ( catMaybes ) +import Data.Word +import Data.Bits {- Note [Avoiding space leaks in toIface*] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -616,6 +620,43 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo lfi = case lfi of + LFReEntrant _ _ arity _ _ -> + IfLFReEntrant arity + LFThunk _ _ updatable sfi mb_fun -> + IfLFThunk updatable (toIfaceStandardFormInfo sfi) mb_fun + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown mb_fun -> + IfLFUnknown mb_fun + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + +toIfaceStandardFormInfo :: StandardFormInfo -> IfaceStandardFormInfo +toIfaceStandardFormInfo NonStandardThunk = IfStandardFormInfo 1 +toIfaceStandardFormInfo sf = + IfStandardFormInfo $! + tag sf .|. encodeField (field sf) + where + tag SelectorThunk{} = 0 + tag ApThunk{} = setBit 0 1 + tag NonStandardThunk = panic "toIfaceStandardFormInfo: NonStandardThunk" + + field (SelectorThunk n) = n + field (ApThunk n) = n + field NonStandardThunk = panic "toIfaceStandardFormInfo: NonStandardThunk" + + encodeField n = + let wn = fromIntegral n :: Word + shifted = wn `unsafeShiftL` 2 + in ASSERT(shifted > 0 && shifted < fromIntegral (maxBound :: Word16)) + (fromIntegral shifted :: Word16) + + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -100,13 +101,13 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +118,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos + Just lf_info -> HsLFInfo (toIfaceLFInfo lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,74 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFThunk !Bool !IfaceStandardFormInfo !Bool + | IfLFCon !Name + | IfLFUnknown !Bool + | IfLFUnlifted + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFThunk updatable sfi mb_fun) = + text "LFThunk" <+> ppr (updatable, tcStandardFormInfo sfi, mb_fun) + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr (IfLFUnknown fun_flag) = + text "LFUnknown" <+> ppr fun_flag + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFThunk updatable sfi mb_fun) = do + putByte bh 1 + put_ bh updatable + put_ bh sfi + put_ bh mb_fun + put_ bh (IfLFCon con_name) = do + putByte bh 2 + put_ bh con_name + put_ bh (IfLFUnknown fun_flag) = do + putByte bh 3 + put_ bh fun_flag + put_ bh IfLFUnlifted = + putByte bh 4 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFThunk <$> get bh <*> get bh <*> get bh + 2 -> IfLFCon <$> get bh + 3 -> IfLFUnknown <$> get bh + 4 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1469,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1930,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2230,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2243,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2575,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,38 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class instances) +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +40,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,26 +55,26 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingCafInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingCafInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom @@ -95,13 +95,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +121,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,7 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1466,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1486,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1501,23 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo lfi = case lfi of + IfLFReEntrant rep_arity -> + return (LFReEntrant TopLevel NoOneShotInfo rep_arity True ArgUnknown) + + IfLFThunk updatable sfi mb_fun -> + return (LFThunk TopLevel True updatable (tcStandardFormInfo sfi) mb_fun) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown fun_flag -> + return (LFUnknown fun_flag) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1583,6 +1604,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,18 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extractInfo info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + ; let !generatedInfo = mkNameEnv (Prelude.map extractInfo (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -70,6 +70,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,77 +189,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - OneShotInfo - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -327,18 +257,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel noOneShotInfo arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel noOneShotInfo arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,174 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !OneShotInfo + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top oneshot rep fvs argdesc) = + text "LFReEntrant" <> brackets (ppr top <+> ppr oneshot <+> + ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = text "LFUnlifted" + ppr LFLetNoEscape = text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,7 +257,7 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one @@ -271,8 +277,9 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) } -- Setters @@ -295,13 +302,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +339,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -220,7 +220,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -287,6 +287,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import A + +main = return () + +a = val + ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , CPR: m1, Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f43a8474e3735a91aaa3525e1214e9bb34d0658c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f43a8474e3735a91aaa3525e1214e9bb34d0658c You're receiving 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 27 20:31:31 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 27 Apr 2020 16:31:31 -0400 Subject: [Git][ghc/ghc][wip/T18105] rts: Make non-existent linker search path merely a warning Message-ID: <5ea74123e5ea1_6167122e22ac74845e4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18105 at Glasgow Haskell Compiler / GHC Commits: 24af9f30 by Ben Gamari at 2020-04-27T16:31:23-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 1 changed file: - rts/linker/PEi386.c Changes: ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24af9f30681444380c25465f555599da563713cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24af9f30681444380c25465f555599da563713cb You're receiving 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 27 21:11:44 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 27 Apr 2020 17:11:44 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18097 Message-ID: <5ea74a90db251_6167c5ce1b07491587@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18097 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18097 You're receiving 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 27 22:28:59 2020 From: gitlab at gitlab.haskell.org (Adam Gundry) Date: Mon, 27 Apr 2020 18:28:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17965 Message-ID: <5ea75cab6c7bc_61673f81cd4c695c7499165@gitlab.haskell.org.mail> Adam Gundry pushed new branch wip/T17965 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17965 You're receiving 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 27 23:52:42 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 27 Apr 2020 19:52:42 -0400 Subject: [Git][ghc/ghc][wip/T17775] More wibbles Message-ID: <5ea7704a5ab21_616711ab08a475039c9@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: c73bb2ec by Simon Peyton Jones at 2020-04-28T00:52:10+01:00 More wibbles - - - - - 17 changed files: - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/dependent/should_fail/T16326_Fail10.stderr - testsuite/tests/typecheck/should_compile/T10072.stderr - testsuite/tests/typecheck/should_fail/tcfail206.stderr Changes: ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -972,12 +972,12 @@ bindLHsTyVarBndr _doc mb_assoc (L loc bindLHsTyVarBndr doc mb_assoc (L loc (KindedTyVar x lrdr@(L lv _) kind)) thing_inside = do { sig_ok <- xoptM LangExt.KindSignatures - ; unless sig_ok (badKindSigErr doc kind) - ; (kind', fvs1) <- rnLHsKind doc kind - ; tv_nm <- newTyVarNameRn mb_assoc lrdr - ; (b, fvs2) <- bindLocalNamesFV [tv_nm] - $ thing_inside (L loc (KindedTyVar x (L lv tv_nm) kind')) - ; return (b, fvs1 `plusFV` fvs2) } + ; unless sig_ok (badKindSigErr doc kind) + ; (kind', fvs1) <- rnLHsKind doc kind + ; tv_nm <- newTyVarNameRn mb_assoc lrdr + ; (b, fvs2) <- bindLocalNamesFV [tv_nm] + $ thing_inside (L loc (KindedTyVar x (L lv tv_nm) kind')) + ; return (b, fvs1 `plusFV` fvs2) } newTyVarNameRn :: Maybe a -> Located RdrName -> RnM Name newTyVarNameRn mb_assoc (L loc rdr) ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -422,10 +422,12 @@ reportImplic ctxt implic@(Implic { ic_skols = tvs | otherwise = do { traceTc "reportImplic" (ppr implic') + ; when bad_telescope $ reportBadTelescope ctxt tcl_env info tvs + -- Do /not/ use the tidied tvs because then are in the + -- wrong order, so tidying will rename things wrongly ; reportWanteds ctxt' tc_lvl wanted ; when (cec_warn_redundant ctxt) $ - warnRedundantConstraints ctxt' tcl_env info' dead_givens - ; when bad_telescope $ reportBadTelescope ctxt' tcl_env info' tvs' } + warnRedundantConstraints ctxt' tcl_env info' dead_givens } where tcl_env = ic_env implic insoluble = isInsolubleStatus status ===================================== compiler/GHC/Tc/Gen/Default.hs ===================================== @@ -70,8 +70,8 @@ tcDefaults decls@(L locn (DefaultDecl _ _) : _) tc_default_ty :: [Class] -> LHsType GhcRn -> TcM Type tc_default_ty deflt_clss hs_ty - = do { (ty, _kind) <- solveEqualities $ - tcInferLHsType hs_ty + = do { ty <- solveEqualities $ + tcInferLHsType hs_ty ; ty <- zonkTcTypeToType ty -- establish Type invariants ; checkValidType DefaultDeclCtxt ty ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -436,11 +436,11 @@ tcExpr expr@(SectionR x op arg2) res_ty = do { (op', op_ty) <- tcInferRhoNC op ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty - ; wrap_res <- tcSubTypeHR SectionOrigin expr - (mkVisFunTy arg1_ty op_res_ty) res_ty ; arg2' <- tcArg (unLoc op) arg2 arg2_ty 2 - ; return ( mkHsWrap wrap_res $ - SectionR x (mkLHsWrap wrap_fun op') arg2' ) } + ; let expr' = SectionR x (mkLHsWrap wrap_fun op') arg2' + act_res_ty = mkVisFunTy arg1_ty op_res_ty + ; tcWrapResultMono expr expr' act_res_ty res_ty } + where fn_orig = lexprCtOrigin op -- It's important to use the origin of 'op', so that call-stacks @@ -456,11 +456,10 @@ tcExpr expr@(SectionL x arg1 op) res_ty ; (wrap_fn, (arg1_ty:arg_tys), op_res_ty) <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) n_reqd_args op_ty - ; wrap_res <- tcSubTypeHR SectionOrigin expr - (mkVisFunTys arg_tys op_res_ty) res_ty ; arg1' <- tcArg (unLoc op) arg1 arg1_ty 1 - ; return ( mkHsWrap wrap_res $ - SectionL x arg1' (mkLHsWrap wrap_fn op') ) } + ; let expr' = SectionL x arg1' (mkLHsWrap wrap_fn op') + act_res_ty = mkVisFunTys arg_tys op_res_ty + ; tcWrapResultMono expr expr' act_res_ty res_ty } where fn_orig = lexprCtOrigin op -- It's important to use the origin of 'op', so that call-stacks @@ -490,18 +489,17 @@ tcExpr expr@(ExplicitTuple x tup_args boxity) res_ty ; arg_tys <- case boxity of { Boxed -> newFlexiTyVarTys arity liftedTypeKind ; Unboxed -> replicateM arity newOpenFlexiTyVarTy } - ; let actual_res_ty - = mkVisFunTys [ty | (ty, (L _ (Missing _))) <- arg_tys `zip` tup_args] - (mkTupleTy1 boxity arg_tys) - -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make - - ; wrap <- tcSubTypeHR (Shouldn'tHappenOrigin "ExpTuple") expr - actual_res_ty res_ty -- Handle tuple sections where ; tup_args1 <- tcTupArgs tup_args arg_tys - ; return $ mkHsWrap wrap (ExplicitTuple x tup_args1 boxity) } + ; let expr' = ExplicitTuple x tup_args1 boxity + act_res_ty = mkVisFunTys [ty | (ty, (L _ (Missing _))) + <- arg_tys `zip` tup_args] + (mkTupleTy1 boxity arg_tys) + -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make + + ; tcWrapResultMono expr expr' act_res_ty res_ty } tcExpr (ExplicitSum _ alt arity expr) res_ty = do { let sum_tc = sumTyCon arity @@ -673,25 +671,26 @@ tcExpr expr@(RecordCon { rcon_con_name = L loc con_name ; checkMissingFields con_like rbinds ; (con_expr, con_sigma) <- tcInferId con_name - ; (con_wrap, con_tau) <- - topInstantiate (OccurrenceOf con_name) con_sigma + ; (con_wrap, con_tau) <- topInstantiate orig con_sigma -- a shallow instantiation should really be enough for -- a data constructor. ; let arity = conLikeArity con_like Right (arg_tys, actual_res_ty) = tcSplitFunTysN arity con_tau - ; case conLikeWrapId_maybe con_like of - Nothing -> nonBidirectionalErr (conLikeName con_like) - Just con_id -> do { - res_wrap <- tcSubTypeHR (Shouldn'tHappenOrigin "RecordCon") - expr actual_res_ty res_ty - ; rbinds' <- tcRecordBinds con_like arg_tys rbinds - ; return $ - mkHsWrap res_wrap $ - RecordCon { rcon_ext = RecordConTc - { rcon_con_like = con_like - , rcon_con_expr = mkHsWrap con_wrap con_expr } - , rcon_con_name = L loc con_id - , rcon_flds = rbinds' } } } + ; case conLikeWrapId_maybe con_like of { + Nothing -> nonBidirectionalErr (conLikeName con_like) ; + Just con_id -> + + do { rbinds' <- tcRecordBinds con_like arg_tys rbinds + ; let rcon_tc = RecordConTc + { rcon_con_like = con_like + , rcon_con_expr = mkHsWrap con_wrap con_expr } + expr' = RecordCon { rcon_ext = rcon_tc + , rcon_con_name = L loc con_id + , rcon_flds = rbinds' } + + ; tcWrapResultMono expr expr' actual_res_ty res_ty } } } + where + orig = OccurrenceOf con_name {- Note [Type of a record update] @@ -942,8 +941,6 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds }) res_ty scrut_ty = TcType.substTy scrut_subst con1_res_ty con1_arg_tys' = map (TcType.substTy result_subst) con1_arg_tys - ; wrap_res <- tcSubTypeHR (exprCtOrigin expr) expr - rec_res_ty res_ty ; co_scrut <- unifyType (Just (unLoc record_expr)) record_rho scrut_ty -- NB: normal unification is OK here (as opposed to subsumption), -- because for this to work out, both record_rho and scrut_ty have @@ -973,16 +970,16 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds }) res_ty ; req_wrap <- instCallConstraints RecordUpdOrigin req_theta' -- Phew! - ; return $ - mkHsWrap wrap_res $ - RecordUpd { rupd_expr - = mkLHsWrap fam_co (mkLHsWrapCo co_scrut record_expr') - , rupd_flds = rbinds' - , rupd_ext = RecordUpdTc - { rupd_cons = relevant_cons - , rupd_in_tys = scrut_inst_tys - , rupd_out_tys = result_inst_tys - , rupd_wrap = req_wrap }} } + ; let upd_tc = RecordUpdTc { rupd_cons = relevant_cons + , rupd_in_tys = scrut_inst_tys + , rupd_out_tys = result_inst_tys + , rupd_wrap = req_wrap } + expr' = RecordUpd { rupd_expr = mkLHsWrap fam_co $ + mkLHsWrapCo co_scrut record_expr' + , rupd_flds = rbinds' + , rupd_ext = upd_tc } + + ; tcWrapResult expr expr' rec_res_ty res_ty } tcExpr e@(HsRecFld _ f) res_ty = tcCheckRecSelId e f res_ty @@ -1401,9 +1398,9 @@ tcArgs fun orig_fun_ty orig_args _ -> ty_app_err upsilon_ty hs_ty_arg } go n so_far fun_ty (HsEValArg loc arg : args) - = do { (wrap, [arg_ty], res_ty) - <- matchActualFunTysPart herald fun_orig (Just fun) - n_val_args so_far 1 fun_ty + = do { (wrap, arg_ty, res_ty) + <- matchActualFunTy herald fun_orig (Just fun) + (n_val_args, so_far) fun_ty ; arg' <- tcArg fun arg arg_ty n ; (args', inner_res_ty) <- go (n+1) (arg_ty:so_far) res_ty args ; return ( addArgWrap wrap $ HsEValArg loc arg' : args' ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcStandaloneKindSig (L _ kisig) = case kisig of StandaloneKindSig _ (L _ name) ksig -> let ctxt = StandaloneKindSigCtxt name in addSigCtxt ctxt (hsSigType ksig) $ - do { mode <- mkTcTyMode KindLevel + do { let mode = mkMode KindLevel ; kind <- tc_top_lhs_type mode ksig (expectedKindInCtxt ctxt) ; checkValidType ctxt kind ; return (name, kind) } @@ -427,8 +427,7 @@ tcStandaloneKindSig (L _ kisig) = case kisig of tcTopLHsType :: LHsSigType GhcRn -> ContextKind -> TcM Type tcTopLHsType hs_ty ctxt_kind - = do { mode <- mkTcTyMode TypeLevel - ; tc_top_lhs_type mode hs_ty ctxt_kind } + = tc_top_lhs_type (mkMode TypeLevel) hs_ty ctxt_kind tc_top_lhs_type :: TcTyMode -> LHsSigType GhcRn -> ContextKind -> TcM Type -- tcTopLHsType is used for kind-checking top-level HsType where @@ -522,7 +521,7 @@ tcHsTypeApp :: LHsWcType GhcRn -> Kind -> TcM Type -- See Note [Recipe for checking a signature] in GHC.Tc.Gen.HsType tcHsTypeApp wc_ty kind | HsWC { hswc_ext = sig_wcs, hswc_body = hs_ty } <- wc_ty - = do { mode <- mkMode TypeLevel HM_VTA + = do { mode <- mkHoleMode TypeLevel HM_VTA -- HM_VTA: See Note [Wildcards in visible type application] ; ty <- addTypeCtxt hs_ty $ solveLocalEqualities "tcHsTypeApp" $ @@ -584,7 +583,7 @@ tcFamTyPats fam_tc hs_pats = do { traceTc "tcFamTyPats {" $ vcat [ ppr fam_tc, text "arity:" <+> ppr fam_arity ] - ; mode <- mkMode TypeLevel HM_FamPat + ; mode <- mkHoleMode TypeLevel HM_FamPat -- HM_FamPat: See Note [Wildcards in family instances] in -- GHC.Rename.Module ; let fun_ty = mkTyConApp fam_tc [] @@ -626,27 +625,28 @@ tcCheckLHsType hs_ty exp_kind do { ek <- newExpectedKind exp_kind ; tcLHsType hs_ty ek } -tcInferLHsType :: LHsType GhcRn -> TcM (TcType, TcKind) +tcInferLHsType :: LHsType GhcRn -> TcM TcType -- Called from outside: set the context -tcInferLHsType hs_ty = addTypeCtxt hs_ty $ - do { mode <- mkTcTyMode TypeLevel - ; tc_infer_lhs_type mode hs_ty } +tcInferLHsType hs_ty + = addTypeCtxt hs_ty $ + do { (ty, _kind) <- tc_infer_lhs_type (mkMode TypeLevel) hs_ty + ; return ty } --- Like tcInferLHsType, but use it in a context where type synonyms and type families --- do not need to be saturated, like in a GHCi :kind call +-- Used to check the argument of GHCi :kind +-- Allow and report wildcards, e.g. :kind T _ +-- Do not saturate family applications: see Note [Dealing with :kind] tcInferLHsTypeUnsaturated :: LHsType GhcRn -> TcM (TcType, TcKind) tcInferLHsTypeUnsaturated hs_ty - | Just (hs_fun_ty, hs_args) <- splitHsAppTys (unLoc hs_ty) = addTypeCtxt hs_ty $ - do { mode <- mkTcTyMode TypeLevel - ; (fun_ty, _ki) <- tcInferAppHead mode hs_fun_ty - ; tcInferTyApps_nosat mode hs_fun_ty fun_ty hs_args } - -- Notice the 'nosat'; do not instantiate trailing - -- invisible arguments of a type family. - -- See Note [Dealing with :kind] - - | otherwise - = tcInferLHsType hs_ty + do { mode <- mkHoleMode TypeLevel HM_Sig -- Allow and report holes + ; case splitHsAppTys (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 } + -- Notice the 'nosat'; do not instantiate trailing + -- invisible arguments of a type family. + -- See Note [Dealing with :kind] + Nothing -> tc_infer_lhs_type mode hs_ty } {- Note [Dealing with :kind] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -695,46 +695,39 @@ data TcTyMode = TcTyMode { mode_tyki :: TypeOrKind -- See Note [Levels for wildcards] - , mode_lvl :: TcLevel - , mode_holes :: HoleMode + -- Nothing <=> no wildcards expected + , mode_holes :: Maybe (TcLevel, HoleMode) } -- HoleMode says how to treat the occurrences -- of anonymous wildcards; see tcAnonWildCardOcc -data HoleMode = HM_NoHoles -- No wildcard expected - | HM_Sig -- Partial type signatures: f :: _ -> Int +data HoleMode = HM_Sig -- Partial type signatures: f :: _ -> Int | HM_FamPat -- Family instances: F _ Int = Bool | HM_VTA -- Visible type and kind application: -- f @(Maybe _) -- Maybe @(_ -> _) -holesOK :: HoleMode -> Bool --- True <=> it's ok to encounter a hole --- Should have been checked by the renamer -holesOK HM_NoHoles = False -holesOK _ = True +mkMode :: TypeOrKind -> TcTyMode +mkMode tyki = TcTyMode { mode_tyki = tyki, mode_holes = Nothing } -mkTcTyMode :: TypeOrKind -> TcM TcTyMode -mkTcTyMode tyki = mkMode tyki HM_NoHoles - -mkMode :: TypeOrKind -> HoleMode -> TcM TcTyMode -mkMode tyki hm +mkHoleMode :: TypeOrKind -> HoleMode -> TcM TcTyMode +mkHoleMode tyki hm = do { lvl <- getTcLevel ; return (TcTyMode { mode_tyki = tyki - , mode_lvl = lvl - , mode_holes = hm }) } + , mode_holes = Just (lvl,hm) }) } + +kindLevel :: TcTyMode -> TcTyMode +kindLevel mode = mode { mode_tyki = KindLevel } instance Outputable HoleMode where - ppr HM_NoHoles = text "HM_NoHoles" ppr HM_Sig = text "HM_Sig" ppr HM_FamPat = text "HM_FamPat" ppr HM_VTA = text "HM_VTA" instance Outputable TcTyMode where - ppr (TcTyMode { mode_tyki = tyki, mode_lvl = lvl, mode_holes = hm }) + ppr (TcTyMode { mode_tyki = tyki, mode_holes = hm }) = text "TcTyMode" <+> braces (sep [ ppr tyki <> comma - , ppr hm <> comma - , text "lvl:" <> ppr lvl ]) + , ppr hm ]) {- Note [Bidirectional type checking] @@ -809,7 +802,7 @@ tc_infer_hs_type mode (HsParTy _ t) tc_infer_hs_type mode ty | Just (hs_fun_ty, hs_args) <- splitHsAppTys ty - = do { (fun_ty, _ki) <- tcInferAppHead mode hs_fun_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) @@ -850,8 +843,7 @@ tc_infer_hs_type mode other_ty ------------------------------------------ tcLHsType :: LHsType GhcRn -> TcKind -> TcM TcType tcLHsType hs_ty exp_kind - = do { mode <- mkTcTyMode TypeLevel - ; tc_lhs_type mode hs_ty exp_kind } + = tc_lhs_type (mkMode TypeLevel) hs_ty exp_kind tc_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType tc_lhs_type mode (L span ty) exp_kind @@ -906,9 +898,13 @@ tc_hs_type mode (HsOpTy _ ty1 (L _ op) ty2) exp_kind tc_hs_type mode forall@(HsForAllTy { hst_fvf = fvf, hst_bndrs = hs_tvs , hst_body = ty }) exp_kind = do { (tclvl, wanted, (tvs', ty')) - <- pushLevelAndCaptureConstraints $ - bindExplicitTKBndrs_Skol hs_tvs $ + <- pushLevelAndCaptureConstraints $ + bindExplicitTKBndrs_Skol_M mode hs_tvs $ + -- The _M variant passes on the mode from the type, to + -- any wildards in kind signatures on the forall'd variables + -- e.g. f :: _ -> Int -> forall (a :: _). blah tc_lhs_type mode ty exp_kind + -- Do not kind-generalise here! See Note [Kind generalisation] -- Why exp_kind? See Note [Body kind of HsForAllTy] ; let argf = case fvf of @@ -1243,14 +1239,14 @@ splitHsAppTys hs_ty go f as = (f, as) --------------------------- -tcInferAppHead :: TcTyMode -> LHsType GhcRn -> TcM (TcType, TcKind) +tcInferTyAppHead :: TcTyMode -> LHsType GhcRn -> TcM (TcType, TcKind) -- Version of tc_infer_lhs_type specialised for the head of an -- application. In particular, for a HsTyVar (which includes type -- constructors, it does not zoom off into tcInferTyApps and family -- saturation -tcInferAppHead mode (L _ (HsTyVar _ _ (L _ tv))) +tcInferTyAppHead mode (L _ (HsTyVar _ _ (L _ tv))) = tcTyVar mode tv -tcInferAppHead mode ty +tcInferTyAppHead mode ty = tc_infer_lhs_type mode ty --------------------------- @@ -1337,8 +1333,7 @@ tcInferTyApps_nosat mode orig_hs_ty fun orig_hs_args , ppr subst ]) ; let exp_kind = substTy subst $ tyBinderType ki_binder - arg_mode = mode { mode_tyki = KindLevel - , mode_holes = HM_VTA } + ; 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 @@ -1654,12 +1649,10 @@ tcHsMbContext Nothing = return [] tcHsMbContext (Just cxt) = tcHsContext cxt tcHsContext :: LHsContext GhcRn -> TcM [PredType] -tcHsContext cxt = do { mode <- mkTcTyMode TypeLevel - ; tc_hs_context mode cxt } +tcHsContext cxt = tc_hs_context (mkMode TypeLevel) cxt tcLHsPredType :: LHsType GhcRn -> TcM PredType -tcLHsPredType pred = do { mode <- mkTcTyMode TypeLevel - ; tc_lhs_pred mode pred } +tcLHsPredType pred = tc_lhs_pred (mkMode TypeLevel) pred tc_hs_context :: TcTyMode -> LHsContext GhcRn -> TcM [PredType] tc_hs_context mode ctxt = mapM (tc_lhs_pred mode) (unLoc ctxt) @@ -1899,20 +1892,19 @@ newNamedWildTyVar _name -- Currently ignoring the "_x" wildcard name used in t --------------------------- tcAnonWildCardOcc :: TcTyMode -> HsType GhcRn -> Kind -> TcM TcType -tcAnonWildCardOcc (TcTyMode { mode_lvl = lvl, mode_holes = hole_mode }) +tcAnonWildCardOcc (TcTyMode { mode_holes = Just (hole_lvl, hole_mode) }) ty exp_kind - -- mode_lvl field: see Note [Checking partial type signatures] - -- esp the bullet on nested forall types - = ASSERT2( holesOK hole_mode, ppr ty ) - do { kv_details <- newTauTvDetailsAtLevel lvl + -- hole_lvl: see Note [Checking partial type signatures] + -- esp the bullet on nested forall types + = do { kv_details <- newTauTvDetailsAtLevel hole_lvl ; kv_name <- newMetaTyVarName (fsLit "k") - ; wc_details <- newTauTvDetailsAtLevel lvl + ; wc_details <- newTauTvDetailsAtLevel hole_lvl ; wc_name <- newMetaTyVarName (fsLit wc_nm) ; let kv = mkTcTyVar kv_name liftedTypeKind kv_details wc_kind = mkTyVarTy kv wc_tv = mkTcTyVar wc_name wc_kind wc_details - ; traceTc "tcAnonWildCardOcc" (ppr lvl <+> ppr emit_holes) + ; traceTc "tcAnonWildCardOcc" (ppr hole_lvl <+> ppr emit_holes) ; when emit_holes $ emitAnonWildCardHoleConstraint wc_tv -- Why the 'when' guard? @@ -1926,14 +1918,19 @@ tcAnonWildCardOcc (TcTyMode { mode_lvl = lvl, mode_holes = hole_mode }) where -- See Note [Wildcard names] wc_nm = case hole_mode of - HM_Sig -> "w" - HM_FamPat -> "_" - HM_VTA -> "w" + HM_Sig -> "w" + HM_FamPat -> "_" + HM_VTA -> "w" emit_holes = case hole_mode of - HM_Sig -> True - HM_FamPat -> False - HM_VTA -> False + HM_Sig -> True + HM_FamPat -> False + HM_VTA -> False + +tcAnonWildCardOcc mode ty _ +-- mode_holes is Nothing. Should not happen, because renamer +-- should already have rejected holes in unexpected places + = pprPanic "tcWildCardOcc" (ppr mode $$ ppr ty) {- Note [Wildcard names] ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2822,9 +2819,16 @@ bindExplicitTKBndrs_Skol, bindExplicitTKBndrs_Tv :: [LHsTyVarBndr GhcRn] -> TcM a -> TcM ([TcTyVar], a) +bindExplicitTKBndrs_Skol_M, bindExplicitTKBndrs_Tv_M + :: TcTyMode + -> [LHsTyVarBndr GhcRn] + -> TcM a + -> TcM ([TcTyVar], a) -bindExplicitTKBndrs_Skol = bindExplicitTKBndrsX (tcHsTyVarBndr newSkolemTyVar) -bindExplicitTKBndrs_Tv = bindExplicitTKBndrsX (tcHsTyVarBndr cloneTyVarTyVar) +bindExplicitTKBndrs_Skol = bindExplicitTKBndrsX (tcHsTyVarBndr (mkMode KindLevel) newSkolemTyVar) +bindExplicitTKBndrs_Skol_M mode = bindExplicitTKBndrsX (tcHsTyVarBndr (kindLevel mode) newSkolemTyVar) +bindExplicitTKBndrs_Tv = bindExplicitTKBndrsX (tcHsTyVarBndr (mkMode KindLevel) cloneTyVarTyVar) +bindExplicitTKBndrs_Tv_M mode = bindExplicitTKBndrsX (tcHsTyVarBndr (kindLevel mode) cloneTyVarTyVar) -- newSkolemTyVar: see Note [Non-cloning for tyvar binders] -- cloneTyVarTyVar: see Note [Cloning for tyvar binders] @@ -2863,13 +2867,13 @@ bindExplicitTKBndrsX tc_tv hs_tvs thing_inside ; return (tv:tvs, res) } ----------------- -tcHsTyVarBndr :: (Name -> Kind -> TcM TyVar) +tcHsTyVarBndr :: TcTyMode -> (Name -> Kind -> TcM TyVar) -> HsTyVarBndr GhcRn -> TcM TcTyVar -tcHsTyVarBndr new_tv (UserTyVar _ (L _ tv_nm)) +tcHsTyVarBndr _ new_tv (UserTyVar _ (L _ tv_nm)) = do { kind <- newMetaKindVar ; new_tv tv_nm kind } -tcHsTyVarBndr new_tv (KindedTyVar _ (L _ tv_nm) lhs_kind) - = do { kind <- tcLHsKindSig (TyVarBndrKindCtxt tv_nm) lhs_kind +tcHsTyVarBndr mode new_tv (KindedTyVar _ (L _ tv_nm) lhs_kind) + = do { kind <- tc_lhs_kind_sig mode (TyVarBndrKindCtxt tv_nm) lhs_kind ; new_tv tv_nm kind } ----------------- @@ -3322,12 +3326,12 @@ tcHsPartialSigType ctxt sig_ty , hsib_body = hs_ty } <- ib_ty , (explicit_hs_tvs, L _ hs_ctxt, hs_tau) <- splitLHsSigmaTyInvis hs_ty = addSigCtxt ctxt hs_ty $ - do { mode <- mkMode TypeLevel HM_Sig + do { mode <- mkHoleMode TypeLevel HM_Sig ; (implicit_tvs, (explicit_tvs, (wcs, wcx, theta, tau))) <- solveLocalEqualities "tcHsPartialSigType" $ tcNamedWildCardBinders sig_wcs $ \ wcs -> - bindImplicitTKBndrs_Tv implicit_hs_tvs $ - bindExplicitTKBndrs_Tv explicit_hs_tvs $ + bindImplicitTKBndrs_Tv implicit_hs_tvs $ + bindExplicitTKBndrs_Tv_M mode explicit_hs_tvs $ do { -- Instantiate the type-class context; but if there -- is an extra-constraints wildcard, just discard it here (theta, wcx) <- tcPartialContext mode hs_ctxt @@ -3457,12 +3461,13 @@ We achieve this as follows: can't unify with skolem 'a'. - For /anonymous/ wildcards, such as 'f' above, we carry the ambient - level of the signature to the hole in the mode_lvl field of - TcTyMode. Then, in tcAnonWildCardOcc we us that level (and /not/ - the level ambient at the occurrence of "_") to create the - unificaiton variable for the wildcard. That is the sole - purpose of the mode_lvl field: to transport the ambient level - of the signature down to the anonymous wildcard occurrences. + level of the signature to the hole in the TcLevel part of the + mode_holes field of TcTyMode. Then, in tcAnonWildCardOcc we us that + level (and /not/ the level ambient at the occurrence of "_") to + create the unification variable for the wildcard. That is the sole + purpose of the TcLevel in the mode_holes field: to transport the + ambient level of the signature down to the anonymous wildcard + occurrences. Note [Extra-constraint holes in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3523,19 +3528,21 @@ tcHsPatSigType :: UserTypeCtxt -- This may emit constraints -- See Note [Recipe for checking a signature] tcHsPatSigType ctxt sig_ty - | HsWC { hswc_ext = sig_wcs, hswc_body = ib_ty } <- sig_ty - , HsIB { hsib_ext = sig_ns - , hsib_body = hs_ty } <- ib_ty + | HsWC { hswc_ext = sig_wcs, hswc_body = ib_ty } <- sig_ty + , HsIB { hsib_ext = sig_ns, hsib_body = hs_ty } <- ib_ty = addSigCtxt ctxt hs_ty $ do { sig_tkv_prs <- mapM new_implicit_tv sig_ns + ; mode <- mkHoleMode TypeLevel HM_Sig ; (wcs, sig_ty) - <- solveLocalEqualities "tcHsPatSigType" $ + <- addTypeCtxt hs_ty $ + solveLocalEqualities "tcHsPatSigType" $ -- Always solve local equalities if possible, -- else casts get in the way of deep skolemisation -- (#16033) tcNamedWildCardBinders sig_wcs $ \ wcs -> tcExtendNameTyVarEnv sig_tkv_prs $ - do { sig_ty <- tcHsOpenType hs_ty + do { ek <- newOpenTypeKind + ; sig_ty <- tc_lhs_type mode hs_ty ek ; return (wcs, sig_ty) } ; emitNamedWildCardHoleConstraints wcs @@ -3638,8 +3645,7 @@ It does sort checking and desugaring at the same time, in one single pass. tcLHsKindSig :: UserTypeCtxt -> LHsKind GhcRn -> TcM Kind tcLHsKindSig ctxt hs_kind - = do { mode <- mkTcTyMode KindLevel - ; tc_lhs_kind_sig mode ctxt hs_kind } + = tc_lhs_kind_sig (mkMode KindLevel) ctxt hs_kind tc_lhs_kind_sig :: TcTyMode -> UserTypeCtxt -> LHsKind GhcRn -> TcM Kind tc_lhs_kind_sig mode ctxt hs_kind ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -376,13 +376,13 @@ tcPatSynSig name sig_ty , hsib_body = hs_ty } <- sig_ty , (univ_hs_tvs, hs_req, hs_ty1) <- splitLHsSigmaTyInvis hs_ty , (ex_hs_tvs, hs_prov, hs_body_ty) <- splitLHsSigmaTyInvis hs_ty1 - = do { traceTc "tcPatSynSig 1" (ppr sig_ty) + = do { traceTc "tcPatSynSig 1" (ppr sig_ty) ; (implicit_tvs, (univ_tvs, (ex_tvs, (req, prov, body_ty)))) <- pushTcLevelM_ $ solveEqualities $ -- See Note [solveEqualities in tcPatSynSig] - bindImplicitTKBndrs_Skol implicit_hs_tvs $ - bindExplicitTKBndrs_Skol univ_hs_tvs $ - bindExplicitTKBndrs_Skol ex_hs_tvs $ + bindImplicitTKBndrs_Skol implicit_hs_tvs $ + bindExplicitTKBndrs_Skol univ_hs_tvs $ + bindExplicitTKBndrs_Skol ex_hs_tvs $ do { req <- tcHsContext hs_req ; prov <- tcHsContext hs_prov ; body_ty <- tcHsOpenType hs_body_ty ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1430,7 +1430,7 @@ reifyInstances th_nm th_tys <- pushTcLevelM_ $ solveEqualities $ -- Avoid error cascade if there are unsolved bindImplicitTKBndrs_Skol tv_names $ - fst <$> tcInferLHsType rn_ty + tcInferLHsType rn_ty ; ty <- zonkTcTypeToType ty -- Substitute out the meta type variables -- In particular, the type might have kind ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -920,11 +920,11 @@ It is conceivable to do a better job at tracking whether or not a type is flattened, but this is left as future work. (Mar '15) -Note [FunTy and decomposing tycon applications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When can_eq_nc' attempts to decompose a tycon application we haven't yet zonked. -This means that we may very well have a FunTy containing a type of some unknown -kind. For instance, we may have, +Note [Decomposing FunTy] +~~~~~~~~~~~~~~~~~~~~~~~~ +can_eq_nc' may attempt to decompose a FunTy that is un-zonked. This +means that we may very well have a FunTy containing a type of some +unknown kind. For instance, we may have, FunTy (a :: k) Int @@ -1020,24 +1020,26 @@ can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1@(LitTy l1) _ (LitTy l2) _ = do { setEvBindIfWanted ev (evCoercion $ mkReflCo (eqRelRole eq_rel) ty1) ; stopWith ev "Equal LitTy" } --- Try to decompose type constructor applications --- Including FunTy (s -> t) -can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1 _ ty2 _ - --- See Note [FunTy and decomposing type constructor applications] - | FunTy { ft_af = af1, ft_arg = ty1a, ft_res = ty1b } <- ty1 - , FunTy { ft_af = af2, ft_arg = ty2a, ft_res = ty2b } <- ty2 - , af1 == af2 -- Don't decompose (Int -> blah) ~ (Show a => blah) - , Just ty1a_rep <- getRuntimeRep_maybe ty1a - , Just ty1b_rep <- getRuntimeRep_maybe ty1b +-- Decompose FunTy: (s -> t) and (c => t) +-- NB: don't decompose (Int -> blah) ~ (Show a => blah) +can_eq_nc' _flat _rdr_env _envs ev eq_rel + (FunTy { ft_af = af1, ft_arg = ty1a, ft_res = ty1b }) _ + (FunTy { ft_af = af2, ft_arg = ty2a, ft_res = ty2b }) _ + | af1 == af2 -- Don't decompose (Int -> blah) ~ (Show a => blah) + , Just ty1a_rep <- getRuntimeRep_maybe ty1a -- getRutimeRep_maybe: + , Just ty1b_rep <- getRuntimeRep_maybe ty1b -- see Note [Decomposing FunTy] , Just ty2a_rep <- getRuntimeRep_maybe ty2a , Just ty2b_rep <- getRuntimeRep_maybe ty2b = canDecomposableTyConAppOK ev eq_rel funTyCon [ty1a_rep, ty1b_rep, ty1a, ty1b] [ty2a_rep, ty2b_rep, ty2a, ty2b] - | TyConApp tc1 tys1 <- ty1 - , TyConApp tc2 tys2 <- ty2 - , not (isTypeFamilyTyCon tc1) +-- Decompose type constructor applications +-- NB: e have expanded type synonyms already +can_eq_nc' _flat _rdr_env _envs ev eq_rel + (TyConApp tc1 tys1) _ + (TyConApp tc2 tys2) _ + | not (isTypeFamilyTyCon tc1) , not (isTypeFamilyTyCon tc2) = canTyConApp ev eq_rel tc1 tys1 tc2 tys2 @@ -1505,7 +1507,6 @@ canTyConApp ev eq_rel tc1 tys1 tc2 tys2 -- the wrong thing (from a pretty printing point of view) -- for functions, because we've lost the AnonArgFlag; but -- in fact we never call canTyConApp on a saturated FunTyCon - -- Note [FunTy and decomposing type constructor applications] ty1 = mkTyConApp tc1 tys1 ty2 = mkTyConApp tc2 tys2 ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2315,18 +2315,18 @@ newtype instance T [a] :: where ... -- See Point 5 2. Where these kinds come from: Return kinds are processed through several different code paths: - data/newtypes: The return kind is part of the TyCon kind, gotten either + Data/newtypes: The return kind is part of the TyCon kind, gotten either by checkInitialKind (standalone kind signature / CUSK) or inferInitialKind. It is extracted by bindTyClTyVars in tcTyClDecl1. It is then passed to tcDataDefn. - families: The return kind is either written in a standalone signature + Families: The return kind is either written in a standalone signature or extracted from a family declaration in getInitialKind. If a family declaration is missing a result kind, it is assumed to be Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - instances: The data family already has a known kind. The return kind + Instances: The data family already has a known kind. The return kind of an instance is then calculated by applying the data family tycon to the patterns provided, as computed by the typeKind lhs_ty in the end of tcDataFamInstHeader. In the case of an instance written in GADT @@ -2362,7 +2362,7 @@ newtype instance T [a] :: where ... -- See Point 5 data T5 :: Bool -- bad data T6 :: Type -> Bool -- bad - Exactly the same applies to data instance (but not data famlily) + Exactly the same applies to data instance (but not data family) declarations. Examples data instance D1 :: Type -- good data instance D2 :: Boool -> Type -- good ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -852,7 +852,7 @@ tcDataFamInstHeader mb_clsinfo fam_tc imp_vars mb_bndrs fixity ; when (isJust m_ksig) $ checkDataKindSig (DataInstanceSort new_or_data) $ snd $ tcSplitPiTys res_kind - -- See Note [Datatype return kinds], end of point (4) + -- See Note [Datatype return kinds], point (4a) -- Check that type patterns match the class instance head -- The call to splitTyConApp_maybe here is just an inlining of ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, - WantedConstraints(..), insolubleWC, insolubleOrImplicWC, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, addInsols, dropMisleading, addSimples, addImplics, @@ -934,7 +934,8 @@ addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } dropMisleading :: WantedConstraints -> WantedConstraints --- Drop misleading constraints +-- Drop misleading constraints; really just class constraints +-- See Note [Constraints and errors] in GHC.Tc.Utils.Monad dropMisleading (WC { wc_simple = simples, wc_impl = implics }) = WC { wc_simple = filterBag keep_ct simples , wc_impl = mapBag drop_implic implics } @@ -943,7 +944,6 @@ dropMisleading (WC { wc_simple = simples, wc_impl = implics }) = implic { ic_wanted = dropMisleading (ic_wanted implic) } keep_ct ct | isHoleCt ct = isOutOfScopeCt ct - | insolubleEqCt ct = True | otherwise = case classifyPredType (ctPred ct) of ClassPred {} -> False _ -> True @@ -965,17 +965,6 @@ insolubleWC (WC { wc_impl = implics, wc_simple = simples }) = anyBag insolubleCt simples || anyBag insolubleImplic implics -insolubleOrImplicWC :: WantedConstraints -> Bool --- Any insoluble simple constraints, or any (non-empty) implications --- The latter are almost certainly skolem-escape violations -insolubleOrImplicWC (WC { wc_impl = implics, wc_simple = simples }) - = anyBag insolubleCt simples - || non_empty_implics implics - where - non_empty_implics = anyBag (non_empty_wc . ic_wanted) - non_empty_wc (WC { wc_impl = implics, wc_simple = simples }) - = not (isEmptyBag simples) || non_empty_implics implics - insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints -- Namely: a) an equality constraint ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -125,7 +125,7 @@ data UserTypeCtxt pprUserTypeCtxt :: UserTypeCtxt -> SDoc pprUserTypeCtxt (FunSigCtxt n _) = text "the type signature for" <+> quotes (ppr n) pprUserTypeCtxt (InfSigCtxt n) = text "the inferred type for" <+> quotes (ppr n) -pprUserTypeCtxt (RuleSigCtxt n) = text "a RULE for" <+> quotes (ppr n) +pprUserTypeCtxt (RuleSigCtxt n) = text "the type signature for" <+> quotes (ppr n) pprUserTypeCtxt ExprSigCtxt = text "an expression type signature" pprUserTypeCtxt KindSigCtxt = text "a kind signature" pprUserTypeCtxt (StandaloneKindSigCtxt n) = text "a standalone kind signature for" <+> quotes (ppr n) ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -429,11 +429,12 @@ mkSynFunTys arg_tys res_ty = foldr SynFun (SynType res_ty) arg_tys {- Note [TcRhoType] ~~~~~~~~~~~~~~~~ -A TcRhoType has no foralls or contexts at the top, or to the right of an arrow - YES (forall a. a->a) -> Int +A TcRhoType has no foralls or contexts at the top NO forall a. a -> Int NO Eq a => a -> a - NO Int -> forall a. a -> Int + YES a -> a + YES (forall a. a->a) -> Int + YES Int -> forall a. a -> Int ************************************************************************ ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -13,8 +13,9 @@ -- | Type subsumption and unification module GHC.Tc.Utils.Unify ( -- Full-blown subsumption - tcWrapResult, tcWrapResultO, tcSkolemise, tcSkolemiseET, - tcSubType, tcSubTypeSigma, tcSubTypePat, tcSubTypeHR, + tcWrapResult, tcWrapResultO, tcWrapResultMono, + tcSkolemise, tcSkolemiseET, + tcSubType, tcSubTypeSigma, tcSubTypePat, checkConstraints, checkTvConstraints, buildImplicationFor, buildTvImplication, emitResidualTvConstraint, @@ -30,7 +31,7 @@ module GHC.Tc.Utils.Unify ( matchExpectedTyConApp, matchExpectedAppTy, matchExpectedFunTys, - matchActualFunTys, matchActualFunTysPart, + matchActualFunTys, matchActualFunTy, matchExpectedFunKind, metaTyVarUpdateOK, occCheckForErrors, MetaTyVarUpdateResult(..) @@ -216,7 +217,7 @@ matchExpectedFunTys herald ctx arity orig_ty thing_inside ; more_arg_tys <- mapM readExpType more_arg_tys ; res_ty <- readExpType res_ty ; let unif_fun_ty = mkVisFunTys more_arg_tys res_ty - ; wrap <- tcSubType AppOrigin GenSigCtxt unif_fun_ty fun_ty + ; wrap <- tcSubType AppOrigin ctx unif_fun_ty fun_ty -- Not a good origin at all :-( ; return (wrap, result) } @@ -237,31 +238,45 @@ matchActualFunTys :: SDoc -- See Note [Herald for matchExpectedFunTys] -> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType -> Arity -> TcSigmaType - -> TcM (HsWrapper, [TcSigmaType], TcSigmaType) --- If matchActualFunTys n ty = (wrap, [t1,..,tn], ty_r) --- then wrap : ty ~> (t1 -> ... -> tn -> ty_r) + -> TcM (HsWrapper, [TcSigmaType], TcRhoType) +-- If matchActualFunTys n ty = (wrap, [t1,..,tn], res_ty) +-- then wrap : ty ~> (t1 -> ... -> tn -> res_ty) +-- and res_ty is a RhoType matchActualFunTys herald ct_orig mb_thing n_val_args_wanted fun_ty - = matchActualFunTysPart herald ct_orig mb_thing - n_val_args_wanted [] - n_val_args_wanted fun_ty + = go n_val_args_wanted [] fun_ty + where + go 0 _ fun_ty + = do { (wrap, rho) <- topInstantiate ct_orig fun_ty + ; return (wrap, [], rho) } + go n so_far fun_ty + = do { (wrap_fun1, arg_ty1, res_ty1) <- matchActualFunTy herald ct_orig mb_thing + (n_val_args_wanted, so_far) + fun_ty + ; (wrap_res, arg_tys, res_ty) <- go (n-1) (arg_ty1:so_far) res_ty1 + ; let wrap_fun2 = mkWpFun idHsWrapper wrap_res arg_ty1 res_ty doc + ; return (wrap_fun2 <.> wrap_fun1, arg_ty1:arg_tys, res_ty) } + where + doc = text "When inferring the argument type of a function with type" <+> + quotes (ppr fun_ty) -- | Variant of 'matchActualFunTys' that works when supplied only part -- (that is, to the right of some arrows) of the full function type -matchActualFunTysPart +matchActualFunTy :: SDoc -- See Note [Herald for matchExpectedFunTys] -> CtOrigin - -> Maybe (HsExpr GhcRn) -- The thing with type TcSigmaType - -> Arity -- Total number of value args in the call - -> [TcSigmaType] -- Types of values args to which function has - -- been applied already (reversed) - -> Arity -- Number of new value args wanted + -> Maybe (HsExpr GhcRn) -- The thing with type TcSigmaType + -> (Arity, [TcSigmaType]) -- Total number of value args in the call, and + -- types of values args to which function has + -- been applied already (reversed) + -- Both are used only for error messages) -> TcSigmaType -- Type to analyse - -> TcM (HsWrapper, [TcSigmaType], TcSigmaType) + -> TcM (HsWrapper, TcSigmaType, TcSigmaType) -- See Note [matchActualFunTys error handling] for all these arguments -matchActualFunTysPart herald ct_orig mb_thing - n_val_args_in_call arg_tys_so_far - n_val_args_wanted fun_ty - = go n_val_args_wanted arg_tys_so_far fun_ty +-- If (wrap, arg_ty, res_ty) = matchActualFunTy ... fun_ty +-- then wrap :: fun_ty ~> (arg_ty -> res_ty) +-- and NB: res_ty is an (uninstantiated) SigmaType +matchActualFunTy herald ct_orig mb_thing err_info fun_ty + = go fun_ty -- Does not allocate unnecessary meta variables: if the input already is -- a function, we just take it apart. Not only is this efficient, -- it's important for higher rank: the argument might be of form @@ -288,40 +303,28 @@ matchActualFunTysPart herald ct_orig mb_thing -- bizarre to build the HsWrapper but not the arg_tys. -- -- Refactoring is welcome. - go :: Arity - -> [TcSigmaType] -- Types of value args to which the function has - -- been applied so far (reversed) - -- Used only for error messages - -> TcSigmaType -- the remainder of the type as we're processing - -> TcM (HsWrapper, [TcSigmaType], TcSigmaType) - go 0 _ ty = return (idHsWrapper, [], ty) - - go n so_far ty - | Just ty' <- tcView ty = go n so_far ty' - - go n so_far ty + go :: TcSigmaType -- the remainder of the type as we're processing + -> TcM (HsWrapper, TcSigmaType, TcSigmaType) + go ty | Just ty' <- tcView ty = go ty' + + go ty | not (null tvs && null theta) = do { (wrap1, rho) <- topInstantiate ct_orig ty - ; (wrap2, arg_tys, res_ty) <- go n so_far rho - ; return (wrap2 <.> wrap1, arg_tys, res_ty) } + ; (wrap2, arg_ty, res_ty) <- go rho + ; return (wrap2 <.> wrap1, arg_ty, res_ty) } where (tvs, theta, _) = tcSplitSigmaTy ty - go n so_far (FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty }) + go (FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty }) = ASSERT( af == VisArg ) - do { (wrap_res, tys, ty_r) <- go (n-1) (arg_ty:so_far) res_ty - ; return ( mkWpFun idHsWrapper wrap_res arg_ty ty_r doc - , arg_ty : tys, ty_r ) } - where - doc = text "When inferring the argument type of a function with type" <+> - quotes (ppr fun_ty) + return (idHsWrapper, arg_ty, res_ty) - go n so_far ty@(TyVarTy tv) + go ty@(TyVarTy tv) | isMetaTyVar tv = do { cts <- readMetaTyVar tv ; case cts of - Indirect ty' -> go n so_far ty' - Flexi -> defer n ty } + Indirect ty' -> go ty' + Flexi -> defer ty } -- In all other cases we bale out into ordinary unification -- However unlike the meta-tyvar case, we are sure that the @@ -338,22 +341,23 @@ matchActualFunTysPart herald ct_orig mb_thing -- -- But in that case we add specialized type into error context -- anyway, because it may be useful. See also #9605. - go n so_far ty = addErrCtxtM (mk_ctxt so_far ty) (defer n ty) + go ty = addErrCtxtM (mk_ctxt ty) (defer ty) ------------ - defer n fun_ty - = do { arg_tys <- replicateM n newOpenFlexiTyVarTy - ; res_ty <- newOpenFlexiTyVarTy - ; let unif_fun_ty = mkVisFunTys arg_tys res_ty + defer fun_ty + = do { arg_ty <- newOpenFlexiTyVarTy + ; res_ty <- newOpenFlexiTyVarTy + ; let unif_fun_ty = mkVisFunTy arg_ty res_ty ; co <- unifyType mb_thing fun_ty unif_fun_ty - ; return (mkWpCastN co, arg_tys, res_ty) } + ; return (mkWpCastN co, arg_ty, res_ty) } ------------ - mk_ctxt :: [TcType] -> TcType -> TidyEnv -> TcM (TidyEnv, MsgDoc) - mk_ctxt arg_tys res_ty env + mk_ctxt :: TcType -> TidyEnv -> TcM (TidyEnv, MsgDoc) + mk_ctxt res_ty env = do { (env', ty) <- zonkTidyTcType env $ - mkVisFunTys (reverse arg_tys) res_ty + mkVisFunTys (reverse arg_tys_so_far) res_ty ; return (env', mk_fun_tys_msg herald ty n_val_args_in_call) } + (n_val_args_in_call, arg_tys_so_far) = err_info mk_fun_tys_msg :: SDoc -> TcType -> Arity -> SDoc mk_fun_tys_msg herald ty n_args_in_call @@ -510,6 +514,35 @@ expected_ty. -} +----------------- +-- tcWrapResult needs both un-type-checked (for origins and error messages) +-- and type-checked (for wrapping) expressions +tcWrapResult :: HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType + -> TcM (HsExpr GhcTcId) +tcWrapResult rn_expr = tcWrapResultO (exprCtOrigin rn_expr) rn_expr + +tcWrapResultO :: CtOrigin -> HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType + -> TcM (HsExpr GhcTcId) +tcWrapResultO orig rn_expr expr actual_ty res_ty + = do { traceTc "tcWrapResult" (vcat [ text "Actual: " <+> ppr actual_ty + , text "Expected:" <+> ppr res_ty ]) + ; wrap <- tcSubTypeNC orig GenSigCtxt (Just rn_expr) actual_ty res_ty + ; return (mkHsWrap wrap expr) } + +tcWrapResultMono :: HsExpr GhcRn -> HsExpr GhcTcId + -> TcRhoType -- Actual -- a rho-type not a sigma-type + -> ExpRhoType -- Expected + -> TcM (HsExpr GhcTcId) +-- A version of tcWrapResult to use when the actual type is a +-- rho-type, so nothing to instantiate; just go straight to unify. +-- It means we don't need to pass in a CtOrigin +tcWrapResultMono rn_expr expr act_ty res_ty + = ASSERT2( isRhoTy act_ty, ppr act_ty $$ ppr rn_expr ) + do { co <- case res_ty of + Infer inf_res -> fillInferResult act_ty inf_res + Check exp_ty -> unifyType (Just rn_expr) act_ty exp_ty + ; return (mkHsWrapCo co expr) } + ------------------------ tcSubTypePat :: CtOrigin -> UserTypeCtxt -> ExpSigmaType -> TcSigmaType -> TcM HsWrapper @@ -527,17 +560,16 @@ tcSubTypePat _ _ (Infer inf_res) ty_expected ; return (mkWpCastN (mkTcSymCo co)) } --------------- -tcSubType :: CtOrigin -> UserTypeCtxt -> TcSigmaType -> ExpRhoType -> TcM HsWrapper +tcSubType :: CtOrigin -> UserTypeCtxt + -> TcSigmaType -- Actual + -> ExpRhoType -- Expected + -> TcM HsWrapper +-- Checks that 'actual' is more polymorphic than 'expected' tcSubType orig ctxt ty_actual ty_expected = addSubTypeCtxt ty_actual ty_expected $ do { traceTc "tcSubType" (vcat [pprUserTypeCtxt ctxt, ppr ty_actual, ppr ty_expected]) ; tcSubTypeNC orig ctxt Nothing ty_actual ty_expected } --- | Call this variant when you are in a higher-rank situation -tcSubTypeHR :: CtOrigin -> HsExpr GhcRn -> TcSigmaType -> ExpRhoType -> TcM HsWrapper -tcSubTypeHR orig expr - = tcSubTypeNC orig GenSigCtxt (Just expr) - tcSubTypeNC :: CtOrigin -- origin used for instantiation only -> UserTypeCtxt -> Maybe (HsExpr GhcRn) -- The expression that has type 'actual' (if known) @@ -699,24 +731,6 @@ to a UserTypeCtxt of GenSigCtxt. Why? See Note [When to build an implication] -} ------------------ --- needs both un-type-checked (for origins) and type-checked (for wrapping) --- expressions -tcWrapResult :: HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType - -> TcM (HsExpr GhcTcId) -tcWrapResult rn_expr = tcWrapResultO (exprCtOrigin rn_expr) rn_expr - --- | Sometimes we don't have a @HsExpr Name@ to hand, and this is more --- convenient. -tcWrapResultO :: CtOrigin -> HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType - -> TcM (HsExpr GhcTcId) -tcWrapResultO orig rn_expr expr actual_ty res_ty - = do { traceTc "tcWrapResult" (vcat [ text "Actual: " <+> ppr actual_ty - , text "Expected:" <+> ppr res_ty ]) - ; cow <- tcSubTypeNC orig GenSigCtxt (Just rn_expr) - actual_ty res_ty - ; return (mkHsWrap cow expr) } - {- ********************************************************************** %* * @@ -1550,7 +1564,7 @@ uUnfilledVar2 origin t_or_k swapped tv1 ty2 swapOverTyVars :: Bool -> TcTyVar -> TcTyVar -> Bool swapOverTyVars is_given tv1 tv2 - -- See Note [Get unification variables on the left] + -- See Note [Unification variables on the left] | not is_given, pri1 == 0, pri2 > 0 = True | not is_given, pri2 == 0, pri1 > 0 = False ===================================== testsuite/tests/dependent/should_fail/T16326_Fail10.stderr ===================================== @@ -3,5 +3,5 @@ T16326_Fail10.hs:12:18: error: • Illegal visible, dependent quantification in the type of a term: forall a -> a -> a (GHC does not yet support this) - • In a RULE for ‘x’: forall a -> a -> a + • In the type signature for ‘x’: forall a -> a -> a When checking the transformation rule "flurmp" ===================================== testsuite/tests/typecheck/should_compile/T10072.stderr ===================================== @@ -6,5 +6,5 @@ T10072.hs:3:31: error: at T10072.hs:3:1-47 To use the inferred type, enable PartialTypeSignatures • In the type ‘a -> _’ - In a RULE for ‘f’: a -> _ + In the type signature for ‘f’: a -> _ When checking the transformation rule "map/empty" ===================================== testsuite/tests/typecheck/should_fail/tcfail206.stderr ===================================== @@ -17,7 +17,7 @@ tcfail206.hs:8:5: error: tcfail206.hs:11:5: error: • Couldn't match type ‘a’ with ‘Bool’ Expected: a -> (a, Bool) - Actual: a -> (a, a) + Actual: a -> (Bool, a) ‘a’ is a rigid type variable bound by the type signature for: c :: forall a. a -> (a, Bool) @@ -45,7 +45,7 @@ tcfail206.hs:17:5: error: tcfail206.hs:20:5: error: • Couldn't match type ‘a’ with ‘Bool’ Expected: a -> (# a, Bool #) - Actual: a -> (# a, a #) + Actual: a -> (# Bool, a #) ‘a’ is a rigid type variable bound by the type signature for: f :: forall a. a -> (# a, Bool #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c73bb2ecfa4aec49a915777adc698bc8839e9e71 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c73bb2ecfa4aec49a915777adc698bc8839e9e71 You're receiving 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 28 00:24:55 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 27 Apr 2020 20:24:55 -0400 Subject: [Git][ghc/ghc][master] TH: fix Show/Eq/Ord instances for Bytes (#16457) Message-ID: <5ea777d7d4788_616711ab08a47510950@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - 5 changed files: - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/th/TH_BytesShowEqOrd.hs - + testsuite/tests/th/TH_BytesShowEqOrd.stdout - testsuite/tests/th/all.T Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -45,12 +45,15 @@ import GHC.Generics ( Generic ) import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), TYPE, RuntimeRep(..) ) 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 import Foreign.ForeignPtr +import Foreign.C.String +import Foreign.C.Types ----------------------------------------------------- -- @@ -1868,7 +1871,45 @@ data Bytes = Bytes -- , bytesInitialized :: Bool -- ^ False: only use `bytesSize` to allocate -- -- an uninitialized region } - deriving (Eq,Ord,Data,Generic,Show) + 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 @{}@ ===================================== libraries/template-haskell/changelog.md ===================================== @@ -10,6 +10,12 @@ and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. + * Fix Eq/Ord instances for `Bytes`: we were comparing pointers while we should + compare the actual bytes (#16457). + + * Fix Show instance for `Bytes`: we were showing the pointer value while we + want to show the contents (#16457). + ## 2.16.0.0 *TBA* * Add support for tuple sections. (#15843) The type signatures of `TupE` and ===================================== testsuite/tests/th/TH_BytesShowEqOrd.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} + +module Main where + +import Language.Haskell.TH.Lib +import GHC.Ptr +import Foreign.ForeignPtr + +main :: IO () +main = do + + let + !x = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"# + !y = "ABCDEabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"# + + p1 <- newForeignPtr_ (Ptr x) + p2 <- newForeignPtr_ (Ptr y) + + let + b1 = mkBytes p1 0 5 + b2 = mkBytes p1 10 5 + b3 = mkBytes p1 26 5 + b4 = mkBytes p2 5 5 + b5 = mkBytes p2 10 5 + + let myCmp a b = putStrLn $ "compare " ++ show a ++ " to " ++ show b ++ " => " ++ show (compare a b) + + putStr "same pointer, same offset, same bytes: " + myCmp b1 b1 + putStr "same pointer, different offset, same bytes: " + myCmp b1 b3 + putStr "same pointer, different offset, different bytes: " + myCmp b1 b2 + putStr "same pointer, different offset, different bytes: " + myCmp b2 b1 + putStr "different pointer, different offset, same bytes: " + myCmp b1 b4 + putStr "different pointer, different offset, different bytes: " + myCmp b1 b5 ===================================== testsuite/tests/th/TH_BytesShowEqOrd.stdout ===================================== @@ -0,0 +1,6 @@ +same pointer, same offset, same bytes: compare abcde to abcde => EQ +same pointer, different offset, same bytes: compare abcde to abcde => EQ +same pointer, different offset, different bytes: compare abcde to klmno => LT +same pointer, different offset, different bytes: compare klmno to abcde => GT +different pointer, different offset, same bytes: compare abcde to abcde => EQ +different pointer, different offset, different bytes: compare abcde to fghij => LT ===================================== testsuite/tests/th/all.T ===================================== @@ -504,3 +504,4 @@ test('T17688a', normal, compile, ['']) test('T17688b', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) +test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99823ed24b22447b14202ca57f75550773c44dbe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99823ed24b22447b14202ca57f75550773c44dbe You're receiving 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 28 00:25:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 27 Apr 2020 20:25:42 -0400 Subject: [Git][ghc/ghc][master] hadrian: always capture both stdout and stderr when running a builder fails Message-ID: <5ea77806dc9c7_61673f81cd9bfa6c7513149@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 1 changed file: - hadrian/src/Builder.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE InstanceSigs, TypeOperators #-} module Builder ( -- * Data types ArMode (..), CcMode (..), ConfigurationInfo (..), GhcMode (..), @@ -14,7 +14,9 @@ module Builder ( applyPatch ) where +import Control.Exception.Extra (Partial) import Development.Shake.Classes +import Development.Shake.Command import GHC.Generics import qualified Hadrian.Builder as H import Hadrian.Builder hiding (Builder) @@ -214,7 +216,7 @@ instance H.Builder Builder where needBuilder builder path <- H.builderPath builder need [path] - Stdout stdout <- cmd [path] ["--no-user-package-db", "field", input, "depends"] + Stdout stdout <- cmd' [path] ["--no-user-package-db", "field", input, "depends"] return stdout _ -> error $ "Builder " ++ show builder ++ " can not be asked!" @@ -231,7 +233,7 @@ instance H.Builder Builder where echo = EchoStdout (verbosity >= Loud) -- Capture stdout and write it to the output file. captureStdout = do - Stdout stdout <- cmd [path] buildArgs + Stdout stdout <- cmd' [path] buildArgs writeFileChanged output stdout case builder of Ar Pack _ -> do @@ -239,54 +241,54 @@ instance H.Builder Builder where if useTempFile then runAr path buildArgs else runArWithoutTempFile path buildArgs - Ar Unpack _ -> cmd echo [Cwd output] [path] buildArgs + Ar Unpack _ -> cmd' echo [Cwd output] [path] buildArgs - Autoreconf dir -> cmd echo [Cwd dir] ["sh", path] buildArgs + Autoreconf dir -> cmd' echo [Cwd dir] ["sh", path] buildArgs Configure dir -> do -- Inject /bin/bash into `libtool`, instead of /bin/sh, -- otherwise Windows breaks. TODO: Figure out why. bash <- bashPath let env = AddEnv "CONFIG_SHELL" bash - cmd echo env [Cwd dir] ["sh", path] buildOptions buildArgs + cmd' echo env [Cwd dir] ["sh", path] buildOptions buildArgs GenApply -> captureStdout GenPrimopCode -> do stdin <- readFile' input - Stdout stdout <- cmd (Stdin stdin) [path] buildArgs + Stdout stdout <- cmd' (Stdin stdin) [path] buildArgs writeFileChanged output stdout GhcPkg Copy _ -> do - Stdout pkgDesc <- cmd [path] + Stdout pkgDesc <- cmd' [path] [ "--expand-pkgroot" , "--no-user-package-db" , "describe" , input -- the package name ] - cmd (Stdin pkgDesc) [path] (buildArgs ++ ["-"]) + cmd' (Stdin pkgDesc) [path] (buildArgs ++ ["-"]) GhcPkg Unregister _ -> do - Exit _ <- cmd echo [path] (buildArgs ++ [input]) + Exit _ <- cmd' echo [path] (buildArgs ++ [input]) return () HsCpp -> captureStdout - Make dir -> cmd echo path ["-C", dir] buildArgs + Make dir -> cmd' echo path ["-C", dir] buildArgs Makeinfo -> do - cmd echo [path] "--no-split" [ "-o", output] [input] + cmd' echo [path] "--no-split" [ "-o", output] [input] Xelatex -> do - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] ["makeindex"] (input -<.> "idx") - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] ["makeindex"] (input -<.> "idx") + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs - Tar _ -> cmd buildOptions echo [path] buildArgs - _ -> cmd echo [path] buildArgs + Tar _ -> cmd' buildOptions echo [path] buildArgs + _ -> cmd' echo [path] buildArgs -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform @@ -366,4 +368,9 @@ applyPatch dir patch = do needBuilder Patch path <- builderPath Patch putBuild $ "| Apply patch " ++ file - quietly $ cmd [Cwd dir, FileStdin file] [path, "-p0"] + quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] + +-- | Wrapper for 'cmd' that makes sure we include both stdout and stderr in +-- Shake's output when any of our builder commands fail. +cmd' :: (Partial, CmdArguments args) => args :-> Action r +cmd' = cmd [WithStderr True, WithStdout True] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c62271a21b1ba1d207aaebf370c87dd884fa6ae1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c62271a21b1ba1d207aaebf370c87dd884fa6ae1 You're receiving 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 28 08:45:39 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 28 Apr 2020 04:45:39 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17873 Message-ID: <5ea7ed33a3d7b_6167c5ce1b07540346@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T17873 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17873 You're receiving 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 28 09:07:10 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 28 Apr 2020 05:07:10 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 3 commits: TH: fix Show/Eq/Ord instances for Bytes (#16457) Message-ID: <5ea7f23e43247_61673f81cd4c695c7550090@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 206b3fe8 by Ömer Sinan Ağacan at 2020-04-28T12:02:45+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 30 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - hadrian/src/Builder.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f43a8474e3735a91aaa3525e1214e9bb34d0658c...206b3fe8693ec0f5d84937c2107681e21811c110 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f43a8474e3735a91aaa3525e1214e9bb34d0658c...206b3fe8693ec0f5d84937c2107681e21811c110 You're receiving 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 28 11:10:26 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 28 Apr 2020 07:10:26 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] 98 commits: Don't override proc CafInfos in ticky builds Message-ID: <5ea80f221f2fc_6167122e22ac759277d@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 8b424afb by Ömer Sinan Ağacan at 2020-04-28T14:10:04+03: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 hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fefd226c19e930a0db4fec9d1b865237e634b789...8b424afbb47c607748ff5169c564c14609493e42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fefd226c19e930a0db4fec9d1b865237e634b789...8b424afbb47c607748ff5169c564c14609493e42 You're receiving 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 28 11:59:58 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 28 Apr 2020 07:59:58 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: TH: fix Show/Eq/Ord instances for Bytes (#16457) Message-ID: <5ea81abec33d2_6167120888bc7606065@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 5259eef1 by Ryan Scott at 2020-04-28T07:59:52-04:00 Define a Quote IO instance Fixes #18103. - - - - - 47b2e153 by Ryan Scott at 2020-04-28T07:59:53-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 15 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - hadrian/src/Builder.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/quotes/T18103.hs - testsuite/tests/quotes/TH_localname.stderr - testsuite/tests/quotes/all.T - + testsuite/tests/th/T18097.hs - + testsuite/tests/th/TH_BytesShowEqOrd.hs - + testsuite/tests/th/TH_BytesShowEqOrd.stdout - testsuite/tests/th/all.T - testsuite/tests/typecheck/should_compile/holes.stderr - testsuite/tests/typecheck/should_compile/holes3.stderr Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -111,6 +111,10 @@ by the user. For those things that *can* appear in source programs, See also Note [Built-in syntax and the OrigNameCache] +Note that one-tuples are an exception to the rule, as they do get assigned +known keys. See +Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys) +in GHC.Builtin.Types. Note [The integer library] ~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -71,7 +71,7 @@ module GHC.Builtin.Types ( -- * Tuples mkTupleTy, mkTupleTy1, mkBoxedTupleTy, mkTupleStr, - tupleTyCon, tupleDataCon, tupleTyConName, + tupleTyCon, tupleDataCon, tupleTyConName, tupleDataConName, promotedTupleDataCon, unitTyCon, unitDataCon, unitDataConId, unitTy, unitTyConKey, pairTyCon, @@ -725,9 +725,13 @@ for one-tuples. So in ghc-prim:GHC.Tuple we see the declarations: data Unit a = Unit a data (a,b) = (a,b) -There is no way to write a boxed one-tuple in Haskell, but it can be -created in Template Haskell or in, e.g., `deriving` code. There is -nothing special about one-tuples in Core; in particular, they have no +There is no way to write a boxed one-tuple in Haskell using tuple syntax. +They can, however, be written using other methods: + +1. They can be written directly by importing them from GHC.Tuple. +2. They can be generated by way of Template Haskell or in `deriving` code. + +There is nothing special about one-tuples in Core; in particular, they have no custom pretty-printing, just using `Unit`. Note that there is *not* a unary constraint tuple, unlike for other forms of @@ -737,6 +741,29 @@ details. See also Note [Flattening one-tuples] in GHC.Core.Make and Note [Don't flatten tuples from HsSyn] in GHC.Core.Make. +----- +-- Wrinkle: Make boxed one-tuple names have known keys +----- + +We make boxed one-tuple names have known keys so that `data Unit a = Unit 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 Unit x -> putStrLn x + +Unless Unit has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an +ExplicitTuple of length 1) will not match the type of Unit (an ordinary +data constructor used in a pattern). Making Unit known-key allows GHC to make +this connection. + +Unlike Unit, every other tuple is /not/ known-key +(see Note [Infinite families of known-key names] in GHC.Builtin.Names). The +main reason for this exception is that other tuples are written with special +syntax, and as a result, they are renamed using a special `isBuiltInOcc_maybe` +function (see Note [Built-in syntax and the OrigNameCache] in GHC.Types.Name.Cache). +In contrast, Unit is just an ordinary data type with no special syntax, so it +doesn't really make sense to handle it in `isBuiltInOcc_maybe`. Making Unit +known-key is the next-best way to teach the internals of the compiler about it. -} -- | Built-in syntax isn't "in scope" so these OccNames map to wired-in Names @@ -760,6 +787,8 @@ isBuiltInOcc_maybe occ = "->" -> Just funTyConName -- boxed tuple data/tycon + -- We deliberately exclude Unit (the boxed 1-tuple). + -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys) "()" -> Just $ tup_name Boxed 0 _ | Just rest <- "(" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest @@ -889,6 +918,9 @@ tupleDataCon sort i | i > mAX_TUPLE_SIZE = snd (mk_tuple sort i) -- Build one tupleDataCon Boxed i = snd (boxedTupleArr ! i) tupleDataCon Unboxed i = snd (unboxedTupleArr ! i) +tupleDataConName :: Boxity -> Arity -> Name +tupleDataConName sort i = dataConName (tupleDataCon sort i) + boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon) boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]] unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]] ===================================== compiler/GHC/Builtin/Utils.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Core.Opt.ConstantFold import GHC.Types.Avail import GHC.Builtin.PrimOps import GHC.Core.DataCon +import GHC.Types.Basic import GHC.Types.Id import GHC.Types.Name import GHC.Types.Name.Env @@ -124,14 +125,17 @@ knownKeyNames = all_names where all_names = + -- We exclude most tuples from this list—see + -- Note [Infinite families of known-key names] in GHC.Builtin.Names. + -- We make an exception for Unit (i.e., the boxed 1-tuple), since it does + -- not use special syntax like other tuples. + -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys) + -- in GHC.Builtin.Types. + tupleTyConName BoxedTuple 1 : tupleDataConName Boxed 1 : concat [ wired_tycon_kk_names funTyCon , concatMap wired_tycon_kk_names primTyCons - , concatMap wired_tycon_kk_names wiredInTyCons - -- Does not include tuples - , concatMap wired_tycon_kk_names typeNatTyCons - , map idName wiredInIds , map (idName . primOpId) allThePrimOps , map (idName . primOpWrapperId) allThePrimOps ===================================== hadrian/src/Builder.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE InstanceSigs, TypeOperators #-} module Builder ( -- * Data types ArMode (..), CcMode (..), ConfigurationInfo (..), GhcMode (..), @@ -14,7 +14,9 @@ module Builder ( applyPatch ) where +import Control.Exception.Extra (Partial) import Development.Shake.Classes +import Development.Shake.Command import GHC.Generics import qualified Hadrian.Builder as H import Hadrian.Builder hiding (Builder) @@ -214,7 +216,7 @@ instance H.Builder Builder where needBuilder builder path <- H.builderPath builder need [path] - Stdout stdout <- cmd [path] ["--no-user-package-db", "field", input, "depends"] + Stdout stdout <- cmd' [path] ["--no-user-package-db", "field", input, "depends"] return stdout _ -> error $ "Builder " ++ show builder ++ " can not be asked!" @@ -231,7 +233,7 @@ instance H.Builder Builder where echo = EchoStdout (verbosity >= Loud) -- Capture stdout and write it to the output file. captureStdout = do - Stdout stdout <- cmd [path] buildArgs + Stdout stdout <- cmd' [path] buildArgs writeFileChanged output stdout case builder of Ar Pack _ -> do @@ -239,54 +241,54 @@ instance H.Builder Builder where if useTempFile then runAr path buildArgs else runArWithoutTempFile path buildArgs - Ar Unpack _ -> cmd echo [Cwd output] [path] buildArgs + Ar Unpack _ -> cmd' echo [Cwd output] [path] buildArgs - Autoreconf dir -> cmd echo [Cwd dir] ["sh", path] buildArgs + Autoreconf dir -> cmd' echo [Cwd dir] ["sh", path] buildArgs Configure dir -> do -- Inject /bin/bash into `libtool`, instead of /bin/sh, -- otherwise Windows breaks. TODO: Figure out why. bash <- bashPath let env = AddEnv "CONFIG_SHELL" bash - cmd echo env [Cwd dir] ["sh", path] buildOptions buildArgs + cmd' echo env [Cwd dir] ["sh", path] buildOptions buildArgs GenApply -> captureStdout GenPrimopCode -> do stdin <- readFile' input - Stdout stdout <- cmd (Stdin stdin) [path] buildArgs + Stdout stdout <- cmd' (Stdin stdin) [path] buildArgs writeFileChanged output stdout GhcPkg Copy _ -> do - Stdout pkgDesc <- cmd [path] + Stdout pkgDesc <- cmd' [path] [ "--expand-pkgroot" , "--no-user-package-db" , "describe" , input -- the package name ] - cmd (Stdin pkgDesc) [path] (buildArgs ++ ["-"]) + cmd' (Stdin pkgDesc) [path] (buildArgs ++ ["-"]) GhcPkg Unregister _ -> do - Exit _ <- cmd echo [path] (buildArgs ++ [input]) + Exit _ <- cmd' echo [path] (buildArgs ++ [input]) return () HsCpp -> captureStdout - Make dir -> cmd echo path ["-C", dir] buildArgs + Make dir -> cmd' echo path ["-C", dir] buildArgs Makeinfo -> do - cmd echo [path] "--no-split" [ "-o", output] [input] + cmd' echo [path] "--no-split" [ "-o", output] [input] Xelatex -> do - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] ["makeindex"] (input -<.> "idx") - unit $ cmd [Cwd output] [path] buildArgs - unit $ cmd [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] ["makeindex"] (input -<.> "idx") + unit $ cmd' [Cwd output] [path] buildArgs + unit $ cmd' [Cwd output] [path] buildArgs - Tar _ -> cmd buildOptions echo [path] buildArgs - _ -> cmd echo [path] buildArgs + Tar _ -> cmd' buildOptions echo [path] buildArgs + _ -> cmd' echo [path] buildArgs -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform @@ -366,4 +368,9 @@ applyPatch dir patch = do needBuilder Patch path <- builderPath Patch putBuild $ "| Apply patch " ++ file - quietly $ cmd [Cwd dir, FileStdin file] [path, "-p0"] + quietly $ cmd' [Cwd dir, FileStdin file] [path, "-p0"] + +-- | Wrapper for 'cmd' that makes sure we include both stdout and stderr in +-- Shake's output when any of our builder commands fail. +cmd' :: (Partial, CmdArguments args) => args :-> Action r +cmd' = cmd [WithStderr True, WithStdout True] ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -45,12 +45,15 @@ import GHC.Generics ( Generic ) import GHC.Types ( Int(..), Word(..), Char(..), Double(..), Float(..), TYPE, RuntimeRep(..) ) 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 import Foreign.ForeignPtr +import Foreign.C.String +import Foreign.C.Types ----------------------------------------------------- -- @@ -122,8 +125,7 @@ class (MonadIO m, MonadFail m) => Quasi m where ----------------------------------------------------- instance Quasi IO where - qNewName s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x)) - ; pure (mkNameU s n) } + qNewName = newNameIO qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) @@ -150,6 +152,13 @@ instance Quasi IO where qIsExtEnabled _ = badIO "isExtEnabled" qExtsEnabled = badIO "extsEnabled" +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" } @@ -1868,7 +1877,45 @@ data Bytes = Bytes -- , bytesInitialized :: Bool -- ^ False: only use `bytesSize` to allocate -- -- an uninitialized region } - deriving (Eq,Ord,Data,Generic,Show) + 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 @{}@ ===================================== libraries/template-haskell/changelog.md ===================================== @@ -10,6 +10,12 @@ and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. + * Fix Eq/Ord instances for `Bytes`: we were comparing pointers while we should + compare the actual bytes (#16457). + + * Fix Show instance for `Bytes`: we were showing the pointer value while we + want to show the contents (#16457). + ## 2.16.0.0 *TBA* * Add support for tuple sections. (#15843) The type signatures of `TupE` and ===================================== testsuite/tests/quotes/T18103.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskellQuotes #-} +module T18103 where + +import Language.Haskell.TH + +ex :: IO [Dec] +ex = [d| foo x = x |] ===================================== testsuite/tests/quotes/TH_localname.stderr ===================================== @@ -7,8 +7,10 @@ TH_localname.hs:3:11: error: x :: t0 -> m0 Language.Haskell.TH.Syntax.Exp (bound at TH_localname.hs:3:1) Probable fix: use a type annotation to specify what ‘m0’ should be. - These potential instance exist: - one instance involving out-of-scope types + These potential instances exist: + instance Language.Haskell.TH.Syntax.Quote IO + -- Defined in ‘Language.Haskell.TH.Syntax’ + ...plus one instance involving out-of-scope types (use -fprint-potential-instances to see them all) • In the expression: [| y |] ===================================== testsuite/tests/quotes/all.T ===================================== @@ -17,6 +17,7 @@ test('T9824', normal, compile, ['-v0']) test('T10384', normal, compile_fail, ['']) test('T16384', req_th, compile, ['']) test('T17857', normal, compile, ['']) +test('T18103', normal, compile, ['']) test('TH_tf2', normal, compile, ['-v0']) test('TH_ppr1', normal, compile_and_run, ['']) ===================================== testsuite/tests/th/T18097.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE TemplateHaskell #-} +module T18097 where + +import Language.Haskell.TH +import GHC.Tuple + +f = case $( tupE [ [| "ok" |] ] ) of Unit x -> putStrLn x +g = case Unit "ok" of $( tupP [ [p| x |] ] ) -> putStrLn x + +h :: $( tupleT 1 ) String +h = Unit "ok" + +i :: Unit String +i = $( tupE [ [| "ok" |] ] ) ===================================== testsuite/tests/th/TH_BytesShowEqOrd.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} + +module Main where + +import Language.Haskell.TH.Lib +import GHC.Ptr +import Foreign.ForeignPtr + +main :: IO () +main = do + + let + !x = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"# + !y = "ABCDEabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"# + + p1 <- newForeignPtr_ (Ptr x) + p2 <- newForeignPtr_ (Ptr y) + + let + b1 = mkBytes p1 0 5 + b2 = mkBytes p1 10 5 + b3 = mkBytes p1 26 5 + b4 = mkBytes p2 5 5 + b5 = mkBytes p2 10 5 + + let myCmp a b = putStrLn $ "compare " ++ show a ++ " to " ++ show b ++ " => " ++ show (compare a b) + + putStr "same pointer, same offset, same bytes: " + myCmp b1 b1 + putStr "same pointer, different offset, same bytes: " + myCmp b1 b3 + putStr "same pointer, different offset, different bytes: " + myCmp b1 b2 + putStr "same pointer, different offset, different bytes: " + myCmp b2 b1 + putStr "different pointer, different offset, same bytes: " + myCmp b1 b4 + putStr "different pointer, different offset, different bytes: " + myCmp b1 b5 ===================================== testsuite/tests/th/TH_BytesShowEqOrd.stdout ===================================== @@ -0,0 +1,6 @@ +same pointer, same offset, same bytes: compare abcde to abcde => EQ +same pointer, different offset, same bytes: compare abcde to abcde => EQ +same pointer, different offset, different bytes: compare abcde to klmno => LT +same pointer, different offset, different bytes: compare klmno to abcde => GT +different pointer, different offset, same bytes: compare abcde to abcde => EQ +different pointer, different offset, different bytes: compare abcde to fghij => LT ===================================== testsuite/tests/th/all.T ===================================== @@ -502,5 +502,7 @@ test('T17511', normal, compile, ['']) test('T17608', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T17688a', normal, compile, ['']) test('T17688b', normal, compile, ['']) +test('T18097', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) +test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) ===================================== testsuite/tests/typecheck/should_compile/holes.stderr ===================================== @@ -90,6 +90,7 @@ holes.hs:11:15: warning: [-Wtyped-holes (in -Wdefault)] Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] + Unit :: forall a. a -> Unit a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a ===================================== testsuite/tests/typecheck/should_compile/holes3.stderr ===================================== @@ -93,6 +93,7 @@ holes3.hs:11:15: error: Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] + Unit :: forall a. a -> Unit a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e74b9ee22e2523141a898cdddf27f0bad398cfb9...47b2e1530fb0758de4b394f23da78c13b178e706 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e74b9ee22e2523141a898cdddf27f0bad398cfb9...47b2e1530fb0758de4b394f23da78c13b178e706 You're receiving 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 28 12:22:42 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 28 Apr 2020 08:22:42 -0400 Subject: [Git][ghc/ghc][wip/T17775] 14 commits: Create di_scoped_tvs for associated data family instances properly Message-ID: <5ea820123859c_6167122e22ac7610491@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 2e141c71 by Simon Peyton Jones at 2020-04-28T13:22:33+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * isTauTy: was replying True for (Show a => a ->a), which is utterly bogus. Fixed. * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 30 changed files: - 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/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c73bb2ecfa4aec49a915777adc698bc8839e9e71...2e141c7157c0fb5d8d9d4c741b008b9a0bdb97d8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c73bb2ecfa4aec49a915777adc698bc8839e9e71...2e141c7157c0fb5d8d9d4c741b008b9a0bdb97d8 You're receiving 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 28 13:26:07 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 28 Apr 2020 09:26:07 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5ea82eef91000_616711ab08a476191b2@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 792c78a2 by Ömer Sinan Ağacan at 2020-04-28T16:25:49+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -74,6 +76,8 @@ import GHC.Types.Demand ( isTopSig ) import GHC.Types.Cpr ( topCprSig ) import Data.Maybe ( catMaybes ) +import Data.Word +import Data.Bits {- Note [Avoiding space leaks in toIface*] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -616,6 +620,43 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo lfi = case lfi of + LFReEntrant _ _ arity _ _ -> + IfLFReEntrant arity + LFThunk _ _ updatable sfi mb_fun -> + IfLFThunk updatable (toIfaceStandardFormInfo sfi) mb_fun + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown mb_fun -> + IfLFUnknown mb_fun + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + +toIfaceStandardFormInfo :: StandardFormInfo -> IfaceStandardFormInfo +toIfaceStandardFormInfo NonStandardThunk = IfStandardFormInfo 1 +toIfaceStandardFormInfo sf = + IfStandardFormInfo $! + tag sf .|. encodeField (field sf) + where + tag SelectorThunk{} = 0 + tag ApThunk{} = setBit 0 1 + tag NonStandardThunk = panic "toIfaceStandardFormInfo: NonStandardThunk" + + field (SelectorThunk n) = n + field (ApThunk n) = n + field NonStandardThunk = panic "toIfaceStandardFormInfo: NonStandardThunk" + + encodeField n = + let wn = fromIntegral n :: Word + shifted = wn `unsafeShiftL` 2 + in ASSERT(shifted > 0 && shifted < fromIntegral (maxBound :: Word16)) + (fromIntegral shifted :: Word16) + + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -100,13 +101,13 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +118,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos + Just lf_info -> HsLFInfo (toIfaceLFInfo lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,74 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFThunk !Bool !IfaceStandardFormInfo !Bool + | IfLFCon !Name + | IfLFUnknown !Bool + | IfLFUnlifted + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFThunk updatable sfi mb_fun) = + text "LFThunk" <+> ppr (updatable, tcStandardFormInfo sfi, mb_fun) + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr (IfLFUnknown fun_flag) = + text "LFUnknown" <+> ppr fun_flag + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFThunk updatable sfi mb_fun) = do + putByte bh 1 + put_ bh updatable + put_ bh sfi + put_ bh mb_fun + put_ bh (IfLFCon con_name) = do + putByte bh 2 + put_ bh con_name + put_ bh (IfLFUnknown fun_flag) = do + putByte bh 3 + put_ bh fun_flag + put_ bh IfLFUnlifted = + putByte bh 4 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFThunk <$> get bh <*> get bh <*> get bh + 2 -> IfLFCon <$> get bh + 3 -> IfLFUnknown <$> get bh + 4 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1469,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1930,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2230,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2243,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2575,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,38 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class instances) +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +40,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,26 +55,26 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingCafInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingCafInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom @@ -95,13 +95,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +121,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,7 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1466,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1486,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1501,23 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo lfi = case lfi of + IfLFReEntrant rep_arity -> + return (LFReEntrant TopLevel NoOneShotInfo rep_arity True ArgUnknown) + + IfLFThunk updatable sfi mb_fun -> + return (LFThunk TopLevel True updatable (tcStandardFormInfo sfi) mb_fun) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown fun_flag -> + return (LFUnknown fun_flag) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1583,6 +1604,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,18 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extractInfo info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + ; let !generatedInfo = mkNameEnv (Prelude.map extractInfo (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -70,6 +70,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,77 +189,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - OneShotInfo - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -327,18 +257,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel noOneShotInfo arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel noOneShotInfo arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,174 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !OneShotInfo + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top oneshot rep fvs argdesc) = + text "LFReEntrant" <> brackets (ppr top <+> ppr oneshot <+> + ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = text "LFUnlifted" + ppr LFLetNoEscape = text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,7 +257,7 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one @@ -271,8 +277,9 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) } -- Setters @@ -295,13 +302,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +339,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -220,7 +220,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -287,6 +287,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import A + +main = return () + +a = val + ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/792c78a2447579f4a140bccf08b82095a60f7248 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/792c78a2447579f4a140bccf08b82095a60f7248 You're receiving 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 28 13:30:48 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 28 Apr 2020 09:30:48 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5ea83008d7a4a_6167120888bc76199a2@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 56c77661 by Ömer Sinan Ağacan at 2020-04-28T16:30:29+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -74,6 +76,8 @@ import GHC.Types.Demand ( isTopSig ) import GHC.Types.Cpr ( topCprSig ) import Data.Maybe ( catMaybes ) +import Data.Word +import Data.Bits {- Note [Avoiding space leaks in toIface*] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -616,6 +620,43 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo lfi = case lfi of + LFReEntrant _ _ arity _ _ -> + IfLFReEntrant arity + LFThunk _ _ updatable sfi mb_fun -> + IfLFThunk updatable (toIfaceStandardFormInfo sfi) mb_fun + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown mb_fun -> + IfLFUnknown mb_fun + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + +toIfaceStandardFormInfo :: StandardFormInfo -> IfaceStandardFormInfo +toIfaceStandardFormInfo NonStandardThunk = IfStandardFormInfo 1 +toIfaceStandardFormInfo sf = + IfStandardFormInfo $! + tag sf .|. encodeField (field sf) + where + tag SelectorThunk{} = 0 + tag ApThunk{} = setBit 0 1 + tag NonStandardThunk = panic "toIfaceStandardFormInfo: NonStandardThunk" + + field (SelectorThunk n) = n + field (ApThunk n) = n + field NonStandardThunk = panic "toIfaceStandardFormInfo: NonStandardThunk" + + encodeField n = + let wn = fromIntegral n :: Word + shifted = wn `unsafeShiftL` 2 + in ASSERT(shifted > 0 && shifted < fromIntegral (maxBound :: Word16)) + (fromIntegral shifted :: Word16) + + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -100,13 +101,13 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +118,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos + Just lf_info -> HsLFInfo (toIfaceLFInfo lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,74 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFThunk !Bool !IfaceStandardFormInfo !Bool + | IfLFCon !Name + | IfLFUnknown !Bool + | IfLFUnlifted + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFThunk updatable sfi mb_fun) = + text "LFThunk" <+> ppr (updatable, tcStandardFormInfo sfi, mb_fun) + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr (IfLFUnknown fun_flag) = + text "LFUnknown" <+> ppr fun_flag + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFThunk updatable sfi mb_fun) = do + putByte bh 1 + put_ bh updatable + put_ bh sfi + put_ bh mb_fun + put_ bh (IfLFCon con_name) = do + putByte bh 2 + put_ bh con_name + put_ bh (IfLFUnknown fun_flag) = do + putByte bh 3 + put_ bh fun_flag + put_ bh IfLFUnlifted = + putByte bh 4 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFThunk <$> get bh <*> get bh <*> get bh + 2 -> IfLFCon <$> get bh + 3 -> IfLFUnknown <$> get bh + 4 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1469,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1930,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2230,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2243,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2575,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,38 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class instances) +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +40,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,26 +55,26 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingCafInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingCafInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom @@ -95,13 +95,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +121,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,7 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1466,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1486,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1501,23 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo lfi = case lfi of + IfLFReEntrant rep_arity -> + return (LFReEntrant TopLevel NoOneShotInfo rep_arity True ArgUnknown) + + IfLFThunk updatable sfi mb_fun -> + return (LFThunk TopLevel True updatable (tcStandardFormInfo sfi) mb_fun) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown fun_flag -> + return (LFUnknown fun_flag) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1583,6 +1604,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,18 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extractInfo info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + ; let !generatedInfo = mkNameEnv (Prelude.map extractInfo (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -70,6 +70,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,77 +189,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - OneShotInfo - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -327,18 +257,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel noOneShotInfo arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel noOneShotInfo arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,174 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !OneShotInfo + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top oneshot rep fvs argdesc) = + text "LFReEntrant" <> brackets (ppr top <+> ppr oneshot <+> + ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = text "LFUnlifted" + ppr LFLetNoEscape = text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,7 +257,7 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one @@ -271,8 +277,9 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) } -- Setters @@ -295,13 +302,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +339,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -220,7 +220,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -287,6 +287,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/56c776617b3a1493f604273e3f111a0641e749a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/56c776617b3a1493f604273e3f111a0641e749a1 You're receiving 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 28 13:45:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 28 Apr 2020 09:45:28 -0400 Subject: [Git][ghc/ghc][wip/T18079] Eta expand un-saturated primops Message-ID: <5ea83378e5a6d_61673f819b417d1c76207ed@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18079 at Glasgow Haskell Compiler / GHC Commits: b0494a52 by Ben Gamari at 2020-04-28T09:45:18-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - 7 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id.hs - testsuite/tests/codeGen/should_fail/T13233.hs - testsuite/tests/codeGen/should_fail/T13233.stderr Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -590,33 +590,85 @@ primOpOcc op = case primOpInfo op of {- Note [Primop wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Previously hasNoBinding would claim that PrimOpIds didn't have a curried -function definition. This caused quite some trouble as we would be forced to -eta expand unsaturated primop applications very late in the Core pipeline. Not -only would this produce unnecessary thunks, but it would also result in nasty -inconsistencies in CAFfy-ness determinations (see #16846 and -Note [CAFfyness inconsistencies due to late eta expansion] in GHC.Iface.Tidy). - -However, it was quite unnecessary for hasNoBinding to claim this; primops in -fact *do* have curried definitions which are found in GHC.PrimopWrappers, which -is auto-generated by utils/genprimops from prelude/primops.txt.pp. These wrappers -are standard Haskell functions mirroring the types of the primops they wrap. -For instance, in the case of plusInt# we would have: + +To support (limited) use of primops in GHCi genprimopcode generates the +GHC.PrimopWrappers module. This module contains a "primop wrapper" +binding for each primop. These are standard Haskell functions mirroring the +types of the primops they wrap. For instance, in the case of plusInt# we would +have: module GHC.PrimopWrappers where import GHC.Prim as P + + plusInt# :: Int# -> Int# -> Int# plusInt# a b = P.plusInt# a b -We now take advantage of these curried definitions by letting hasNoBinding -claim that PrimOpIds have a curried definition and then rewrite any unsaturated -PrimOpId applications that we find during CoreToStg as applications of the -associated wrapper (e.g. `GHC.Prim.plusInt# 3#` will get rewritten to -`GHC.PrimopWrappers.plusInt# 3#`).` The Id of the wrapper for a primop can be -found using 'PrimOp.primOpWrapperId'. +The Id for the wrapper of a primop can be found using +'GHC.Builtin.PrimOp.primOpWrapperId'. However, GHCi does not use this mechanism +to link primops; it rather does a rather hacky symbol lookup (see +GHC.ByteCode.Linker.primopToCLabel). TODO: Perhaps this should be changed? + +Note that these wrappers aren't *quite* +as expressive as their unwrapped breathern in that they may exhibit less levity +polymorphism. For instance, consider the case of mkWeakNoFinalizer# which has +type: + + mkWeakNoFinalizer# :: forall (r :: RuntimeRep) (k :: TYPE r) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +Naively we could generate a wrapper of the form, + + + mkWeakNoFinalizer# k v s = GHC.Prim.mkWeakNoFinalizer# k v s + +However, this would require that 'k' bind the levity-polymorphic key, +which is disallowed by our levity polymorphism validity checks (see Note +[Levity polymorphism invariants] in GHC.Core). Consequently, we give the +wrapper the simpler, less polymorphic type + + mkWeakNoFinalizer# :: forall (k :: Type) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +This simplification tends to be good enough for GHCi uses given that there are +few levity polymorphic primops and we do little simplification on interpreted +code anyways. + +TODO: This behavior is actually wrong; a program becomes ill-typed upon +replacing a real primop occurrence with one of its wrapper due to the fact that +the former has an additional type binder. Hmmm.... + +Note [Eta expanding primops] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +STG requires that primop applications be saturated. This makes code generation +significantly simpler since otherwise we would need to define a calling +convention for curried applications that can accomodate levity polymorphism. + +To ensure saturation, CorePrep eta expands expand all primop applications as +described in Note [Eta expansion of hasNoBinding things in CorePrep] in +GHC.Core.Prep. + +Historical Note: + +For a short period around GHC 8.8 we rewrote unsaturated primop applications to +rather use the primop's wrapper (see Note [Primop wrappers] in +GHC.Builtin.PrimOps) instead of eta expansion. This was because at the time +CoreTidy would try to predict the CAFfyness of bindings that would be produced +by CorePrep for inclusion in interface files. Eta expanding during CorePrep +proved to be very difficult to predict, leading to nasty inconsistencies in +CAFfyness determinations (see #16846). -Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's -used by GHCi, which does not implement primops direct at all. +Thankfully, we now no longer try to predict CAFfyness but rather compute it on +GHC STG (see Note [SRTs] in GHC.Cmm.Info.Build) and inject it into the interface +file after code generation (see TODO: Refer to whatever falls out of #18096). +This is much simpler and avoids the potential for inconsistency, allowing us to +return to the somewhat simpler eta expansion approach for unsaturated primops. +See #18079. -} -- | Returns the 'Id' of the wrapper associated with the given 'PrimOp'. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -176,6 +176,7 @@ nameToCLabel n suffix = mkFastString label ] +-- See Note [Primop wrappers] in GHC.Builtin.PrimOps primopToCLabel :: PrimOp -> String -> String primopToCLabel primop suffix = concat [ "ghczmprim_GHCziPrimopWrappers_" ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -45,7 +45,7 @@ import GHC.Driver.Session import GHC.Driver.Ways import GHC.Types.ForeignCall import GHC.Types.Demand ( isUsedOnce ) -import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) +import GHC.Builtin.PrimOps ( PrimCall(..) ) import GHC.Types.SrcLoc ( mkGeneralSrcSpan ) import GHC.Builtin.Names ( unsafeEqualityProofName ) @@ -539,12 +539,10 @@ coreToStgApp f args ticks = do (dropRuntimeRepArgs (fromMaybe [] (tyConAppArgs_maybe res_ty))) -- Some primitive operator that might be implemented as a library call. - -- As described in Note [Primop wrappers] in GHC.Builtin.PrimOps, here we - -- turn unsaturated primop applications into applications of - -- the primop's wrapper. - PrimOpId op - | saturated -> StgOpApp (StgPrimOp op) args' res_ty - | otherwise -> StgApp (primOpWrapperId op) args' + -- As noted by Note [Eta expanding primops] in GHC.Builtin.PrimOps + -- we require that primop applications be saturated. + PrimOpId op -> ASSERT( saturated ) + StgOpApp (StgPrimOp op) args' res_ty -- A call to some primitive Cmm function. FCallId (CCall (CCallSpec (StaticTarget _ lbl (Just pkgId) True) ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -71,7 +71,7 @@ import qualified Data.Set as S The goal of this pass is to prepare for code generation. -1. Saturate constructor applications. +1. Saturate constructor and primop applications. 2. Convert to A-normal form; that is, function arguments are always variables. @@ -1067,15 +1067,11 @@ maybeSaturate deals with eta expanding to saturate things that can't deal with unsaturated applications (identified by 'hasNoBinding', currently just foreign calls and unboxed tuple/sum constructors). -Note that eta expansion in CorePrep is very fragile due to the "prediction" of -CAFfyness made during tidying (see Note [CAFfyness inconsistencies due to eta -expansion in CorePrep] in GHC.Iface.Tidy for details. We previously saturated primop +Historical Note: Note that eta expansion in CorePrep used to be very fragile +due to the "prediction" of CAFfyness that we used to make during tidying. +We previously saturated primop applications here as well but due to this fragility (see #16846) we now deal with this another way, as described in Note [Primop wrappers] in GHC.Builtin.PrimOps. - -It's quite likely that eta expansion of constructor applications will -eventually break in a similar way to how primops did. We really should -eliminate this case as well. -} maybeSaturate :: Id -> CpeApp -> Int -> UniqSM CpeRhs ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -515,20 +515,12 @@ hasNoBinding :: Id -> Bool -- ^ Returns @True@ of an 'Id' which may not have a -- binding, even though it is defined in this module. --- Data constructor workers used to be things of this kind, but --- they aren't any more. Instead, we inject a binding for --- them at the CorePrep stage. --- --- 'PrimOpId's also used to be of this kind. See Note [Primop wrappers] in GHC.Builtin.PrimOps. --- for the history of this. --- --- Note that CorePrep currently eta expands things no-binding things and this --- can cause quite subtle bugs. See Note [Eta expansion of hasNoBinding things --- in CorePrep] in CorePrep for details. --- --- EXCEPT: unboxed tuples, which definitely have no binding +-- Data constructor workers used to be things of this kind, but they aren't any +-- more. Instead, we inject a binding for them at the CorePrep stage. The +-- exception to this is unboxed tuples and sums datacons, which definitely have +-- no binding hasNoBinding id = case Var.idDetails id of - PrimOpId _ -> False -- See Note [Primop wrappers] in GHC.Builtin.PrimOps + PrimOpId _ -> True -- See Note [Eta expanding primops] in GHC.Builtin.PrimOps FCallId _ -> True DataConWorkId dc -> isUnboxedTupleCon dc || isUnboxedSumCon dc _ -> isCompulsoryUnfolding (idUnfolding id) ===================================== testsuite/tests/codeGen/should_fail/T13233.hs ===================================== @@ -21,9 +21,6 @@ obscure _ = () quux :: () quux = obscure (#,#) --- It used to be that primops has no binding. However, as described in --- Note [Primop wrappers] in GHC.Builtin.PrimOps we now rewrite unsaturated primop --- applications to their wrapper, which allows safe use of levity polymorphism. primop :: forall (rep :: RuntimeRep) (a :: TYPE rep) b c. a -> b -> (State# RealWorld -> (# State# RealWorld, c #)) -> State# RealWorld -> (# State# RealWorld, Weak# b #) ===================================== testsuite/tests/codeGen/should_fail/T13233.stderr ===================================== @@ -20,3 +20,11 @@ T13233.hs:22:16: error: Levity-polymorphic arguments: a :: TYPE rep1 b :: TYPE rep2 + +T13233.hs:27:10: error: + Cannot use function with levity-polymorphic arguments: + mkWeak# :: a + -> b + -> (State# RealWorld -> (# State# RealWorld, c #)) + -> State# RealWorld + -> (# State# RealWorld, Weak# b #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0494a52537ac18e07560b5cc6e230d0cb2a8351 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0494a52537ac18e07560b5cc6e230d0cb2a8351 You're receiving 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 28 13:46:02 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 28 Apr 2020 09:46:02 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Introduce a standard thunk for allocating strings Message-ID: <5ea8339a23067_616787c09cc76211f6@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 3a39d538 by Ömer Sinan Ağacan at 2020-04-28T16:45:53+03: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 hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - 6 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Closure.hs - includes/stg/MiscClosures.h - rts/RtsSymbols.c - rts/StgStdThunks.cmm Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Cmm.CLabel ( mkConInfoTableLabel, mkApEntryLabel, mkApInfoTableLabel, + mkMkStringInfoTableLabel, mkClosureTableLabel, mkBytesLabel, @@ -61,6 +62,7 @@ module GHC.Cmm.CLabel ( mkCAFBlackHoleInfoTableLabel, mkRtsPrimOpLabel, mkRtsSlowFastTickyCtrLabel, + mkRtsMkStringLabel, mkSelectorInfoLabel, mkSelectorEntryLabel, @@ -427,6 +429,8 @@ data RtsLabelInfo | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks | RtsApEntry Bool{-updatable-} Int{-arity-} + | RtsMkStringInfoTable + | RtsPrimOp PrimOp | RtsApFast FastString -- ^ _fast versions of generic apply | RtsSlowFastTickyCtr String @@ -570,16 +574,16 @@ mkLocalBlockLabel u = LocalBlockLabel u mkRtsPrimOpLabel :: PrimOp -> CLabel mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop) -mkSelectorInfoLabel :: Bool -> Int -> CLabel -mkSelectorEntryLabel :: Bool -> Int -> CLabel +mkSelectorInfoLabel, mkSelectorEntryLabel :: Bool -> Int -> CLabel mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off) mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off) -mkApInfoTableLabel :: Bool -> Int -> CLabel -mkApEntryLabel :: Bool -> Int -> CLabel +mkApInfoTableLabel, mkApEntryLabel :: Bool -> Int -> CLabel mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off) mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off) +mkMkStringInfoTableLabel :: CLabel +mkMkStringInfoTableLabel = RtsLabel RtsMkStringInfoTable -- A call to some primitive hand written Cmm code mkPrimCallLabel :: PrimCall -> CLabel @@ -672,6 +676,8 @@ mkRtsApFastLabel str = RtsLabel (RtsApFast str) mkRtsSlowFastTickyCtrLabel :: String -> CLabel mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat) +mkRtsMkStringLabel :: CLabel +mkRtsMkStringLabel = RtsLabel RtsMkStringInfoTable -- Constructing Code Coverage Labels mkHpcTicksLabel :: Module -> CLabel @@ -1297,6 +1303,8 @@ pprCLbl dflags = \case (CCS_Label ccs) -> ppr ccs (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") + (RtsLabel RtsMkStringInfoTable) -> text "stg_MK_STRING_info" + (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" (AsmTempDerivedLabel {}) -> panic "pprCLbl AsmTempDerivedLabel" (DynamicLinkerLabel {}) -> panic "pprCLbl DynamicLinkerLabel" ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -51,6 +51,8 @@ import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Driver.Session +import GHC.Builtin.Names (unpackCStringName) + import Control.Monad ------------------------------------------------------------------------ @@ -76,6 +78,9 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = lf_info = mkClosureLFInfo platform id TopLevel [] upd_flag args in (cg_id_info, gen_code dflags lf_info closure_label) where + + gen_code :: DynFlags -> LambdaFormInfo -> CLabel -> FCode () + -- special case for a indirection (f = g). We create an IND_STATIC -- closure pointing directly to the indirectee. This is exactly -- what the CAF will eventually evaluate to anyway, we're just @@ -90,11 +95,34 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = -- concurrent/should_run/4030 fails, for instance. -- gen_code _ _ closure_label - | StgApp f [] <- body, null args, isNonRec rec + | StgApp f [] <- body + , null args + , isNonRec rec = do cg_info <- getCgIdInfo f emitDataCon closure_label indStaticInfoTable ccs [unLit (idInfoToAmode cg_info)] + gen_code _ _ closure_label + | StgApp f [arg] <- stripStgTicksTopE (not . tickishIsCode) body + , idName f == unpackCStringName + = do -- TODO: What to do with ticks? + pprTrace "unpackCString#" (ppr body) (return ()) + arg' <- getArgAmode (NonVoid arg) + case arg' of + CmmLit lit -> do + let payload = [lit] + let info = CmmInfoTable + { cit_lbl = mkRtsMkStringLabel + , cit_rep = HeapRep True 0 1 Thunk + , cit_prof = NoProfilingInfo + , cit_srt = Nothing + , cit_clo = Nothing + } + emitDecl (CmmData (Section Data closure_label) (CmmStatics closure_label info ccs payload)) + + _ -> panic "cgTopRhsClosure.gen_code" + + gen_code dflags lf_info _closure_label = do { let name = idName id ; mod_name <- getModuleName @@ -222,6 +250,34 @@ mkRhsClosure :: DynFlags -> Id -> CostCentreStack -> CgStgExpr -> FCode (CgIdInfo, FCode CmmAGraph) +{- + TODO: Consider handling this too. Not sure if it's going to save us much to + so this needs benchmarking. + +---------- unpackCString# -------------------- +mkRhsClosure dflags bndr _cc + [] -- No free variables, because this is top-level + Updatable -- Updatable thunk + [] -- A thunk + expr + + | let expr_no_ticks = stripStgTicksTopE (not . tickishIsCode) expr + , StgApp fn [arg] <- expr + , idName fn == unpackCStringName + = -- TODO: What to do with ticks? + -- A non-top-level unpackCString# closure. Most unpackCString# closures are + -- floted to the top-level, but sometimes we see simplifier-generated thunks + -- like: + -- + -- sat_sK0 [Occ=Once] :: [GHC.Types.Char] + -- [LclId] = + -- {} \u [] + -- GHC.CString.unpackCString# + -- "Oops! The program has entered an `absent' argument!\n"#; + -- + pprPanic "mkRhsClosure" (text "unpackCString# closure:" <+> ppr expr) +-} + {- mkRhsClosure looks for two special forms of the right-hand side: a) selector thunks b) AP thunks @@ -375,7 +431,8 @@ mkRhsClosure dflags bndr cc fvs upd_flag args body ------------------------- cgRhsStdThunk - :: Id + :: HasCallStack + => Id -> LambdaFormInfo -> [StgArg] -- payload -> FCode (CgIdInfo, FCode CmmAGraph) @@ -432,7 +489,8 @@ mkClosureLFInfo platform bndr top fvs upd_flag args -- The code for closures ------------------------------------------------------------------------ -closureCodeBody :: Bool -- whether this is a top-level binding +closureCodeBody :: HasCallStack + => Bool -- whether this is a top-level binding -> Id -- the closure's name -> ClosureInfo -- Lots of information about this closure -> CostCentreStack -- Optional cost centre attached to closure ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -258,7 +258,6 @@ data StandardFormInfo -- in the RTS to save space. RepArity -- Arity, n - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -666,7 +665,7 @@ data ClosureInfo } -- | Convert from 'ClosureInfo' to 'CmmInfoTable'. -mkCmmInfo :: ClosureInfo -> Id -> CostCentreStack -> CmmInfoTable +mkCmmInfo :: HasCallStack => ClosureInfo -> Id -> CostCentreStack -> CmmInfoTable mkCmmInfo ClosureInfo {..} id ccs = CmmInfoTable { cit_lbl = closureInfoLabel , cit_rep = closureSMRep ===================================== includes/stg/MiscClosures.h ===================================== @@ -241,6 +241,10 @@ RTS_THUNK(stg_ap_5_upd); RTS_THUNK(stg_ap_6_upd); RTS_THUNK(stg_ap_7_upd); +/* the `unpackCString# ...` thunk */ + +RTS_THUNK(stg_MK_STRING); + /* standard application routines (see also utils/genapply, * and GHC.StgToCmm.ArgRep). */ ===================================== rts/RtsSymbols.c ===================================== @@ -913,6 +913,7 @@ SymI_HasProto(stg_sel_13_noupd_info) \ SymI_HasProto(stg_sel_14_noupd_info) \ SymI_HasProto(stg_sel_15_noupd_info) \ + SymI_HasProto(stg_MK_STRING_info) \ SymI_HasProto(stg_upd_frame_info) \ SymI_HasProto(stg_bh_upd_frame_info) \ SymI_HasProto(suspendThread) \ ===================================== rts/StgStdThunks.cmm ===================================== @@ -13,6 +13,8 @@ #include "Cmm.h" #include "Updates.h" +import CLOSURE ghczmprim_GHCziCString_unpackCStringzh_info; + /* ----------------------------------------------------------------------------- The code for a thunk that simply extracts a field from a single-constructor datatype depends only on the offset of the field @@ -284,3 +286,26 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") StgThunk_payload(node,6)); } } + +/* ----------------------------------------------------------------------------- + Making strings + -------------------------------------------------------------------------- */ + +INFO_TABLE(stg_MK_STRING, 0, 1, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") + (P_ node) +{ + W_ newCAF_ret; + + (newCAF_ret) = ccall newCAF(BaseReg "ptr", node "ptr"); + + if (newCAF_ret == 0) { + LDV_ENTER(node); + } else { + // TODO: Stack checks? + Sp_adj(-2); + Sp(1) = node; + Sp(0) = stg_bh_upd_frame_info; + jump ghczmprim_GHCziCString_unpackCStringzh_info(StgThunk_payload(node,0)); + + } +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a39d53833746c0b025815b1a604c294c63ca385 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a39d53833746c0b025815b1a604c294c63ca385 You're receiving 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 28 14:00:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 28 Apr 2020 10:00:49 -0400 Subject: [Git][ghc/ghc][wip/keepAlive] 6 commits: XXX: Don't apply Note [dodgy unsafeCoerce 1] to join points Message-ID: <5ea83711184_61673f81cd9bfa6c76235c8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/keepAlive at Glasgow Haskell Compiler / GHC Commits: 3a3b8290 by Ben Gamari at 2020-04-25T00:39:40+00:00 XXX: Don't apply Note [dodgy unsafeCoerce 1] to join points - - - - - 0aab3dc6 by Ben Gamari at 2020-04-27T20:13:36+00:00 A new approach To avoid violating the let/app invariant we now give keepAlive# the type: keepAlive# :: o -> State# RW -> (State# RW -> p) -> p The awkward argument ordering probably ought to be changed but was driven by a desire to stay as close to runRW's implementation as possible for the time being. - - - - - 999419ec by Ben Gamari at 2020-04-27T23:44:06+00:00 Fix occur analysis - - - - - d43307b5 by Ben Gamari at 2020-04-28T02:42:12+00:00 Fix warning - - - - - 00d7411a by Ben Gamari at 2020-04-28T02:42:34+00:00 Fix eta expansion - - - - - d7c7772e by Ben Gamari at 2020-04-28T02:42:53+00:00 Fix potential loop - - - - - 15 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/StgToCmm/Expr.hs - + compiler/GHC/StgToCmm/Expr.hs-boot - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/Foreign/Marshal/Alloc.hs - libraries/base/GHC/ForeignPtr.hs - libraries/ghc-compact/GHC/Compact/Serialized.hs Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -89,7 +89,7 @@ defaults -- conditions. Now that `foreign import prim` exists, only those primops -- which have both internal and external implementations ought to be -- this file. The rest aren't really primops, since they don't need --- bespoke compiler support but just a general way to interface with +-- bespoke iompiler support but just a general way to interface with -- C--. They are just foreign calls. -- -- Unfortunately, for the time being most of the primops which should be @@ -3240,10 +3240,10 @@ primop SeqOp "seq#" GenPrimOp -- See Note [seq# magic] in GHC.Core.Op.ConstantFold primop KeepAliveOp "keepAlive#" GenPrimOp - o -> p -> p + o -> State# RealWorld -> (State# RealWorld -> p) -> p { TODO. } with - strictness = { \ _arity -> mkClosedStrictSig [topDmd, strictApply1Dmd] topDiv } + strictness = { \ _arity -> mkClosedStrictSig [topDmd, topDmd, strictApply1Dmd] topDiv } primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) ===================================== compiler/GHC/Core.hs ===================================== @@ -450,7 +450,7 @@ which will generate a @case@ if necessary The let/app invariant is initially enforced by mkCoreLet and mkCoreApp in GHC.Core.Make. -For discussion of some implications of the let/app invariant primops see +For discussion of some implications of the let/app invariant on primops see Note [Checking versus non-checking primops] in GHC.Builtin.PrimOps. Note [Case expression invariants] ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -33,6 +33,7 @@ import GHC.Core.Opt.Monad import Bag import GHC.Types.Literal import GHC.Core.DataCon +import GHC.Builtin.PrimOps ( PrimOp(KeepAliveOp) ) import GHC.Builtin.Types.Prim import GHC.Tc.Utils.TcType ( isFloatingTy ) import GHC.Types.Var as Var @@ -927,16 +928,30 @@ lintCoreExpr e@(App _ _) = failWithL (text "Invalid runRW# application") | Var fun <- fun - , Just KeepAliveOp <- isPrimOpId_maybe f - , [arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5, arg6] <- args - = do { fun_ty6 <- lintCoreArgs (idType fun) - [ arg_ty1, arg_ty2, arg_ty3, arg_ty4, arg5 ] - ; arg6_ty <- lintJoinLams 0 (Just fun) arg6 -- f :: State# RW -> (# State# RW, o #) - ; lintValApp arg6 fun_ty6 arg6_ty + , Just KeepAliveOp <- isPrimOpId_maybe fun + , arg_rep : arg_ty : res_rep : res_ty : arg : s : k : rest <- args + = pprTrace "keepAlive Lint" empty $ + do { fun_ty1 <- lintCoreArgs (idType fun) + [ arg_rep, arg_ty, res_rep, res_ty, arg, s ] + ; let lintRunRWCont :: CoreArg -> LintM LintedType + lintRunRWCont (Cast expr co) = do + ty <- lintRunRWCont expr + lintCastExpr expr ty co + lintRunRWCont expr@(Lam _ _) = do + lintJoinLams 1 (Just fun) expr + lintRunRWCont (Var v) + | isJoinId v + , idJoinArity v == 1 + = return (idType v) + lintRunRWCont other = markAllJoinsBad $ lintCoreExpr other + -- TODO: Look through ticks? + ; k_ty <- lintRunRWCont k + ; fun_ty2 <- lintValApp k fun_ty1 k_ty + ; lintCoreArgs fun_ty2 rest } | Var fun <- fun - , Just KeepAliveOp <- isPrimOpId_maybe f + , Just KeepAliveOp <- isPrimOpId_maybe fun = failWithL (text "Invalid keepAlive# application") | otherwise ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -40,6 +40,7 @@ import Digraph ( SCC(..), Node(..) , stronglyConnCompFromEdgedVerticesUniq , stronglyConnCompFromEdgedVerticesUniqR ) import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.PrimOps( PrimOp(KeepAliveOp) ) import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set @@ -1890,6 +1891,14 @@ occAnalApp env (Var fun, args, ticks) , let (usage, arg') = occAnalRhs env (Just 1) arg = (usage, mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']) + | Just KeepAliveOp <- isPrimOpId_maybe fun + , [r1, t1, r2, t2, x, s, k] <- args + , let (usages, xs) = occAnalArgs env [r1, t1, r2, t2, x, s] [[], []] + , let (k_usage, k') = occAnalRhs env (Just 1) k + = ( markAllNonTailCalled usages `andUDs` k_usage + , mkTicks ticks $ mkApps (Var fun) (xs ++ [k']) + ) + | otherwise = (all_uds, mkTicks ticks $ mkApps fun' args') where ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -96,9 +96,10 @@ import GHC.Core.Type ( Type, mkLamTypes, splitTyConApp_maybe, tyCoVarsOfType , mightBeUnliftedType, closeOverKindsDSet ) import GHC.Types.Basic ( Arity, RecFlag(..), isRec ) import GHC.Core.DataCon ( dataConOrigResTy ) +import GHC.Builtin.Names ( runRWKey ) +import GHC.Builtin.PrimOps ( PrimOp(KeepAliveOp) ) import GHC.Builtin.Types import GHC.Types.Unique.Supply -import GHC.Builtin.Names ( runRWKey ) import Util import Outputable import FastString @@ -402,7 +403,7 @@ isContPrimOp :: Id -> Bool isContPrimOp fn | fn `hasKey` runRWKey = True | Just KeepAliveOp <- isPrimOpId_maybe fn = True - | otherwise = Falsej + | otherwise = False lvlApp :: LevelEnv -> CoreExprWithFVs ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -37,8 +37,9 @@ import GHC.Core.DataCon , StrictnessMark (..) ) import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) ) import GHC.Core -import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) +import GHC.Builtin.PrimOps ( PrimOp(SeqOp, KeepAliveOp) ) import GHC.Builtin.Names( runRWKey ) +import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) import GHC.Types.Cpr ( mkCprSig, botCpr ) @@ -61,7 +62,6 @@ import FastString import Util import ErrUtils import GHC.Types.Module ( moduleName, pprModuleName ) -import GHC.Builtin.PrimOps ( PrimOp (SeqOp) ) {- @@ -1955,9 +1955,11 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont -- ~> -- keepAlive# @arg_rep @arg_ty @out_rep @out_ty x (\s -> K[rhs]) s0 rebuildContPrimop :: SimplEnv -> ArgInfo -> SimplCont -> Maybe (SimplM (SimplFloats, OutExpr)) -rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont +rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) + (ApplyToVal { sc_arg = k, sc_env = k_se, sc_cont = cont}) | Just KeepAliveOp <- isPrimOpId_maybe fun - , [ ValArg y + , not (contIsStop cont) -- Don't fiddle around if the continuation is boring + , [ ValArg s0 , ValArg x , TyArg {} -- res_ty , TyArg {} -- res_rep @@ -1965,27 +1967,30 @@ rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont , TyArg {as_arg_ty=arg_rep} ] <- rev_args = Just $ do - { let ty' = contResultType cont - ; j <- newJoinId [] ty' + { s <- newId (fsLit "s") realWorldStatePrimTy + ; let k_env = (k_se `setInScopeFromE` env) `addNewInScopeIds` [s] + k_cont = ApplyToVal { sc_dup = Simplified, sc_arg = Var s + , sc_env = k_env, sc_cont = cont } + ; k' <- simplExprC k_env k k_cont ; let env' = zapSubstEnv env - ; y' <- simplExprC env' y cont - ; let bind = NonRec j y' + ; s0' <- simplExpr env' s0 ; x' <- simplExpr env' x ; arg_rep' <- simplType env' arg_rep ; arg_ty' <- simplType env' arg_ty - ; let call' = mkApps (Var fun) + ; let ty' = contResultType cont + call' = mkApps (Var fun) [ mkTyArg arg_rep', mkTyArg arg_ty' , mkTyArg (getRuntimeRep ty'), mkTyArg ty' , x' - , Var j + , s0' + , Lam s k' ] - ; --pprTrace "rebuild keepAlive" (ppr fun $$ ppr rev_args $$ ppr cont) $ - return (emptyFloats env `extendFloats` bind, call') } + ; return (emptyFloats env, call') } -- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o -- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) rebuildContPrimop env (ArgInfo { ai_fun = fun, ai_args = rev_args }) - (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) + (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) | fun `hasKey` runRWKey , not (contIsStop cont) -- Don't fiddle around if the continuation is boring , [ TyArg {}, TyArg {} ] <- rev_args ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -24,9 +24,9 @@ import GHC.Core.Opt.OccurAnal import GHC.Driver.Types import GHC.Builtin.Names -import GHC.Builtin.PrimOps ( PrimOp(TouchOp) ) import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) -import GHC.Types.Id.Make ( mkPrimOpId, realWorldPrimId ) +import GHC.Builtin.PrimOps ( PrimOp(KeepAliveOp) ) +import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Core.Utils import GHC.Core.Arity import GHC.Core.FVs @@ -58,7 +58,7 @@ import GHC.Driver.Ways import Util import Outputable import FastString -import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName ) +import GHC.Types.Name ( mkSystemVarName, NamedThing(..), nameSrcSpan, isInternalName ) import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc ) import Data.Bits import MonadUtils ( mapAccumLM ) @@ -781,18 +781,10 @@ runRW# strict (which we do in GHC.Types.Id.Make), this can't happen Note [CorePrep handling of keepAlive#] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Lower keepAlive# applications to touch#. Specifically: +TODO keepAlive# @a @r @b x k s0 -is lowered to: - - case k s of _b0 { (# y, s1 #) -> - case touch# @a x s1 of s2 { _ -> - (# y, s2 #) - } - } - -} cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) @@ -866,16 +858,30 @@ cpeApp top_env expr -- See Note [CorePrep handling of keepAlive#] cpe_app env (Var f) [CpeApp (Type arg_rep), CpeApp (Type arg_ty), - CpeApp (Type _result_rep), CpeApp (Type result_ty), - CpeApp x, CpeApp y] 2 + CpeApp (Type result_rep), CpeApp (Type result_ty), + CpeApp x, CpeApp s, CpeApp y] _n | Just KeepAliveOp <- isPrimOpId_maybe f - = do { y' <- newVar result_ty - ; s2 <- newVar realWorldStatePrimTy - ; let touchId = mkPrimOpId TouchOp - expr = Case y y' result_ty [(DEFAULT, [], rhs1)] - rhs1 = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, x, Var realWorldPrimId] - in Case scrut s2 result_ty [(DEFAULT, [], Var y')] - ; pprTrace "cpe_app" (ppr expr) $ cpeBody env expr + = do { uniq <- getUniqueM + ; let name = mkSystemVarName uniq (fsLit "$j") + ty = (mkVisFunTy realWorldStatePrimTy result_ty) + id_info = vanillaIdInfo `setArityInfo` 1 + bndr = mkLocalVar (JoinId 1) name ty id_info + -- We need to transform the application into ANF so we must bind + -- the continuation. However, since it might contain join points + -- we must join-bind it. We must eta expand to ensure that we meet + -- the required join arity. + ; (bndr', rhs) <- cpeJoinPair env bndr $ case etaExpandToJoinPoint 1 y of + (bndrs, body) -> mkLams bndrs body + ; (x_floats, x') <- cpeArg env evalDmd x arg_ty + ; (s_floats, s') <- cpeArg env evalDmd s realWorldStatePrimTy + ; let body = pprTrace "cpe_app" (ppr expr) $ + Let (NonRec bndr' rhs) $ + mkApps (Var f) + [ Type arg_rep, Type arg_ty + , Type result_rep, Type result_ty + , x', s', Var bndr + ] + ; return (x_floats `appendFloats` s_floats, body) } cpe_app _env (Var f) args n | Just KeepAliveOp <- isPrimOpId_maybe f ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -54,7 +54,6 @@ import ErrUtils ( MsgDoc, Severity(..), mkLocMessage ) import GHC.Core.Type import GHC.Types.RepType import GHC.Types.SrcLoc -import GHC.Types.Unique ( hasKey ) import Outputable import GHC.Types.Module ( Module ) import qualified ErrUtils as Err @@ -183,9 +182,6 @@ lintStgExpr app@(StgConApp con args _arg_tys) = do mapM_ lintStgArg args mapM_ checkPostUnariseConArg args -lintStgExpr (StgOpApp (StgPrimOp KeepAliveOp) _ _) = - addErrL (text "keepAlive# should have been desugared by CorePrep") - lintStgExpr (StgOpApp _ args _) = mapM_ lintStgArg args ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -364,6 +364,7 @@ assignment. -} cgCase (StgApp v []) bndr alt_type@(PrimAlt _) alts | isUnliftedType (idType v) -- Note [Dodgy unsafeCoerce 1] + , not $ isJoinId v -- TODO: necessary as idInfoToAmode panics on LneLoc = -- assignment suffices for unlifted types do { platform <- getPlatform ; unless (reps_compatible platform) $ ===================================== compiler/GHC/StgToCmm/Expr.hs-boot ===================================== @@ -0,0 +1,6 @@ +module GHC.StgToCmm.Expr ( cgExpr ) where + +import GHC.Stg.Syntax +import GHC.StgToCmm.Monad + +cgExpr :: CgStgExpr -> FCode ReturnKind ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -26,6 +26,7 @@ module GHC.StgToCmm.Prim ( import GhcPrelude hiding ((<*>)) +import {-# SOURCE #-} GHC.StgToCmm.Expr ( cgExpr ) import GHC.StgToCmm.Layout import GHC.StgToCmm.Foreign import GHC.StgToCmm.Env @@ -38,6 +39,7 @@ import GHC.StgToCmm.Prof ( costCentreFrom ) import GHC.Driver.Session import GHC.Platform import GHC.Types.Basic +import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Cmm.BlockId import GHC.Cmm.Graph import GHC.Stg.Syntax @@ -82,6 +84,16 @@ cgOpApp (StgFCallOp fcall ty) stg_args res_ty = cgForeignCall fcall ty stg_args res_ty -- Note [Foreign call results] +cgOpApp (StgPrimOp KeepAliveOp) args _res_ty + | [x, s, StgVarArg k] <- args = do + { emitComment $ fsLit "keepAlive#" + ; r <- cgExpr (StgApp k [s]) + ; cmm_args <- getNonVoidArgAmodes [x, StgVarArg realWorldPrimId] + ; emitPrimCall [] MO_Touch cmm_args + ; return r + } + | otherwise = pprPanic "ill-formed keepAlive#" (ppr args) + cgOpApp (StgPrimOp primop) args res_ty = do dflags <- getDynFlags cmm_args <- getNonVoidArgAmodes args @@ -1522,6 +1534,8 @@ emitPrimOp dflags = \case TraceMarkerOp -> alwaysExternal SetThreadAllocationCounter -> alwaysExternal + KeepAliveOp -> panic "keepAlive# should have been desugared by CorePrep" + where platform = targetPlatform dflags alwaysExternal = \_ -> PrimopCmmEmit_External ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -76,7 +76,7 @@ import GHC.Driver.Session import Outputable import FastString import ListSetOps -import GHC.Types.Var (VarBndr(Bndr), setIdDetails) +import GHC.Types.Var (VarBndr(Bndr)) import qualified GHC.LanguageExtensions as LangExt import Data.Maybe ( maybeToList ) ===================================== libraries/base/Foreign/Marshal/Alloc.hs ===================================== @@ -68,7 +68,6 @@ import GHC.IO.Exception import GHC.Real import GHC.Ptr import GHC.Base -import GHC.Prim ( keepAlive# ) -- exported functions -- ------------------ @@ -131,7 +130,7 @@ allocaBytes (I# size) action = IO $ \ s0 -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> let addr = Ptr (byteArrayContents# barr#) in case action addr of { IO action' -> - keepAlive# barr# (action' s2) + keepAlive# barr# s2 action' }}} allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b @@ -140,7 +139,7 @@ allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> let addr = Ptr (byteArrayContents# barr#) in case action addr of { IO action' -> - keepAlive# barr# (action' s2) + keepAlive# barr# s2 action' }}} -- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes' ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -55,7 +55,6 @@ import GHC.Base import GHC.IORef import GHC.STRef ( STRef(..) ) import GHC.Ptr ( Ptr(..), FunPtr(..) ) -import GHC.Prim ( keepAlive# ) import Unsafe.Coerce ( unsafeCoerce, unsafeCoerceUnlifted ) @@ -412,7 +411,7 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b -- 'Storable' class. withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s -> case f (unsafeForeignPtrToPtr fo) of - IO action# -> keepAlive# r (action# s) + IO action# -> keepAlive# r s action# touchForeignPtr :: ForeignPtr a -> IO () ===================================== libraries/ghc-compact/GHC/Compact/Serialized.hs ===================================== @@ -90,7 +90,7 @@ withSerializedCompact (Compact buffer root lock) func = withMVar lock $ \_ -> do (# s', rootAddr #) -> (# s', Ptr rootAddr #) ) blockList <- mkBlockList buffer let serialized = SerializedCompact blockList rootPtr - IO (\s1 -> case func serialized of IO action' -> keepAlive# buffer (action' s1)) + IO (\s1 -> case func serialized of IO action' -> keepAlive# buffer s1 action') fixupPointers :: Addr# -> Addr# -> State# RealWorld -> (# State# RealWorld, Maybe (Compact a) #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2d1c15280223204390ad37c4d0ecbbf9a1348fb...d7c7772eccd9a3c9e3e0882a935f232f42f5b3f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2d1c15280223204390ad37c4d0ecbbf9a1348fb...d7c7772eccd9a3c9e3e0882a935f232f42f5b3f0 You're receiving 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 28 14:20:09 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 28 Apr 2020 10:20:09 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/dmdanal-precise-exn-simpl Message-ID: <5ea83b99afa23_61673f819b417d1c7624286@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/dmdanal-precise-exn-simpl You're receiving 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 28 19:40:14 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 28 Apr 2020 15:40:14 -0400 Subject: [Git][ghc/ghc][master] Define a Quote IO instance Message-ID: <5ea8869ed5822_6167e5b152c76931dc@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 4 changed files: - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - + testsuite/tests/quotes/T18103.hs - testsuite/tests/quotes/TH_localname.stderr - testsuite/tests/quotes/all.T Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -125,8 +125,7 @@ class (MonadIO m, MonadFail m) => Quasi m where ----------------------------------------------------- instance Quasi IO where - qNewName s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x)) - ; pure (mkNameU s n) } + qNewName = newNameIO qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg) @@ -153,6 +152,13 @@ instance Quasi IO where qIsExtEnabled _ = badIO "isExtEnabled" qExtsEnabled = badIO "extsEnabled" +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" } ===================================== testsuite/tests/quotes/T18103.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskellQuotes #-} +module T18103 where + +import Language.Haskell.TH + +ex :: IO [Dec] +ex = [d| foo x = x |] ===================================== testsuite/tests/quotes/TH_localname.stderr ===================================== @@ -7,8 +7,10 @@ TH_localname.hs:3:11: error: x :: t0 -> m0 Language.Haskell.TH.Syntax.Exp (bound at TH_localname.hs:3:1) Probable fix: use a type annotation to specify what ‘m0’ should be. - These potential instance exist: - one instance involving out-of-scope types + These potential instances exist: + instance Language.Haskell.TH.Syntax.Quote IO + -- Defined in ‘Language.Haskell.TH.Syntax’ + ...plus one instance involving out-of-scope types (use -fprint-potential-instances to see them all) • In the expression: [| y |] ===================================== testsuite/tests/quotes/all.T ===================================== @@ -17,6 +17,7 @@ test('T9824', normal, compile, ['-v0']) test('T10384', normal, compile_fail, ['']) test('T16384', req_th, compile, ['']) test('T17857', normal, compile, ['']) +test('T18103', normal, compile, ['']) test('TH_tf2', normal, compile, ['-v0']) test('TH_ppr1', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b9764db7c190de377c06dfc71bfe6e4b37c7eb0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b9764db7c190de377c06dfc71bfe6e4b37c7eb0 You're receiving 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 28 19:40:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 28 Apr 2020 15:40:52 -0400 Subject: [Git][ghc/ghc][master] Make boxed 1-tuples have known keys Message-ID: <5ea886c47b9fe_61673f81cd9bfa6c7697462@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 7 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - + testsuite/tests/th/T18097.hs - testsuite/tests/th/all.T - testsuite/tests/typecheck/should_compile/holes.stderr - testsuite/tests/typecheck/should_compile/holes3.stderr Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -111,6 +111,10 @@ by the user. For those things that *can* appear in source programs, See also Note [Built-in syntax and the OrigNameCache] +Note that one-tuples are an exception to the rule, as they do get assigned +known keys. See +Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys) +in GHC.Builtin.Types. Note [The integer library] ~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -71,7 +71,7 @@ module GHC.Builtin.Types ( -- * Tuples mkTupleTy, mkTupleTy1, mkBoxedTupleTy, mkTupleStr, - tupleTyCon, tupleDataCon, tupleTyConName, + tupleTyCon, tupleDataCon, tupleTyConName, tupleDataConName, promotedTupleDataCon, unitTyCon, unitDataCon, unitDataConId, unitTy, unitTyConKey, pairTyCon, @@ -725,9 +725,13 @@ for one-tuples. So in ghc-prim:GHC.Tuple we see the declarations: data Unit a = Unit a data (a,b) = (a,b) -There is no way to write a boxed one-tuple in Haskell, but it can be -created in Template Haskell or in, e.g., `deriving` code. There is -nothing special about one-tuples in Core; in particular, they have no +There is no way to write a boxed one-tuple in Haskell using tuple syntax. +They can, however, be written using other methods: + +1. They can be written directly by importing them from GHC.Tuple. +2. They can be generated by way of Template Haskell or in `deriving` code. + +There is nothing special about one-tuples in Core; in particular, they have no custom pretty-printing, just using `Unit`. Note that there is *not* a unary constraint tuple, unlike for other forms of @@ -737,6 +741,29 @@ details. See also Note [Flattening one-tuples] in GHC.Core.Make and Note [Don't flatten tuples from HsSyn] in GHC.Core.Make. +----- +-- Wrinkle: Make boxed one-tuple names have known keys +----- + +We make boxed one-tuple names have known keys so that `data Unit a = Unit 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 Unit x -> putStrLn x + +Unless Unit has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an +ExplicitTuple of length 1) will not match the type of Unit (an ordinary +data constructor used in a pattern). Making Unit known-key allows GHC to make +this connection. + +Unlike Unit, every other tuple is /not/ known-key +(see Note [Infinite families of known-key names] in GHC.Builtin.Names). The +main reason for this exception is that other tuples are written with special +syntax, and as a result, they are renamed using a special `isBuiltInOcc_maybe` +function (see Note [Built-in syntax and the OrigNameCache] in GHC.Types.Name.Cache). +In contrast, Unit is just an ordinary data type with no special syntax, so it +doesn't really make sense to handle it in `isBuiltInOcc_maybe`. Making Unit +known-key is the next-best way to teach the internals of the compiler about it. -} -- | Built-in syntax isn't "in scope" so these OccNames map to wired-in Names @@ -760,6 +787,8 @@ isBuiltInOcc_maybe occ = "->" -> Just funTyConName -- boxed tuple data/tycon + -- We deliberately exclude Unit (the boxed 1-tuple). + -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys) "()" -> Just $ tup_name Boxed 0 _ | Just rest <- "(" `BS.stripPrefix` name , (commas, rest') <- BS.span (==',') rest @@ -889,6 +918,9 @@ tupleDataCon sort i | i > mAX_TUPLE_SIZE = snd (mk_tuple sort i) -- Build one tupleDataCon Boxed i = snd (boxedTupleArr ! i) tupleDataCon Unboxed i = snd (unboxedTupleArr ! i) +tupleDataConName :: Boxity -> Arity -> Name +tupleDataConName sort i = dataConName (tupleDataCon sort i) + boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon) boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]] unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]] ===================================== compiler/GHC/Builtin/Utils.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Core.Opt.ConstantFold import GHC.Types.Avail import GHC.Builtin.PrimOps import GHC.Core.DataCon +import GHC.Types.Basic import GHC.Types.Id import GHC.Types.Name import GHC.Types.Name.Env @@ -124,14 +125,17 @@ knownKeyNames = all_names where all_names = + -- We exclude most tuples from this list—see + -- Note [Infinite families of known-key names] in GHC.Builtin.Names. + -- We make an exception for Unit (i.e., the boxed 1-tuple), since it does + -- not use special syntax like other tuples. + -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys) + -- in GHC.Builtin.Types. + tupleTyConName BoxedTuple 1 : tupleDataConName Boxed 1 : concat [ wired_tycon_kk_names funTyCon , concatMap wired_tycon_kk_names primTyCons - , concatMap wired_tycon_kk_names wiredInTyCons - -- Does not include tuples - , concatMap wired_tycon_kk_names typeNatTyCons - , map idName wiredInIds , map (idName . primOpId) allThePrimOps , map (idName . primOpWrapperId) allThePrimOps ===================================== testsuite/tests/th/T18097.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE TemplateHaskell #-} +module T18097 where + +import Language.Haskell.TH +import GHC.Tuple + +f = case $( tupE [ [| "ok" |] ] ) of Unit x -> putStrLn x +g = case Unit "ok" of $( tupP [ [p| x |] ] ) -> putStrLn x + +h :: $( tupleT 1 ) String +h = Unit "ok" + +i :: Unit String +i = $( tupE [ [| "ok" |] ] ) ===================================== testsuite/tests/th/all.T ===================================== @@ -502,6 +502,7 @@ test('T17511', normal, compile, ['']) test('T17608', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T17688a', normal, compile, ['']) test('T17688b', normal, compile, ['']) +test('T18097', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) ===================================== testsuite/tests/typecheck/should_compile/holes.stderr ===================================== @@ -90,6 +90,7 @@ holes.hs:11:15: warning: [-Wtyped-holes (in -Wdefault)] Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] + Unit :: forall a. a -> Unit a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a ===================================== testsuite/tests/typecheck/should_compile/holes3.stderr ===================================== @@ -93,6 +93,7 @@ holes3.hs:11:15: error: Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] + Unit :: forall a. a -> Unit a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9 You're receiving 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 28 20:14:27 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 28 Apr 2020 16:14:27 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ea88ea3b182b_6167120888bc76997ea@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: beed9626 by Sebastian Graf at 2020-04-28T22:14:18+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/beed9626427e06ae4d5aff0d9af728149da3cf03 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/beed9626427e06ae4d5aff0d9af728149da3cf03 You're receiving 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 28 21:08:12 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Tue, 28 Apr 2020 17:08:12 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] 57 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5ea89b3c8cb33_6167e5b152c77156b9@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - 6c112c6b by Alan Zimmerman at 2020-04-28T22:06:31+01:00 Proof of Concept implementation of in-tree API Annotations This MR introduces a possible machinery to introduce API Annotations into the TTG extension points. It is intended to be a concrete example for discussion. It still needs to process comments. ---- Work in progress, adding more TTG extensions for annotations. And fixing ppr round-trip tests by being able to blank out in-tree annotations, as done with SrcSpans. This is needed for the case of class Foo a where for which current ppr does not print the "where". Rename AA to AddApiAnn and AA to AddAnn Add XConPatIn and XConPatOut Rebase ---- First pass at bringing in LocatedA for API anns in locations Treatment of ECP in parsing is provisional at this stage, leads to some horribly stuff in Parser.y and RdrHsSyn. It is an extensive but not invasive change. I think (AZ). Locally it reports some parsing tests using less memory. Add ApiAnns to the HsExpr data structure. rebase. Change HsMatchContext and HsStmtContext to use an id, not a GhcPass parameter. Add ApiAnns to Hs/Types Rebase Rebased 2020-03-25 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan ---- In-tree annotations: LHsDecl and LHsBind LocatedA ---- WIP on in-tree annotations ---- in-tree annotations: LHsType is now LocatedA ---- FunDeps is now also a HS data type ---- WIP. Added LocatedA to Pat, Expr, Decl And worked some more through Parser.y ---- LStmt now Located ---- Finished working through Parser.y, tests seem ok failures relate to annotations. - - - - - 30 changed files: - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/PPC/RegInfo.hs - compiler/GHC/CmmToAsm/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs - compiler/GHC/CmmToAsm/SPARC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/ShortcutJump.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Class.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/18d70ea2e803677f10042c6d13e1117c77ea951d...6c112c6b7bd35e622410b3e0035c886b5742c5df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/18d70ea2e803677f10042c6d13e1117c77ea951d...6c112c6b7bd35e622410b3e0035c886b5742c5df You're receiving 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 28 23:13:12 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 28 Apr 2020 19:13:12 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Define a Quote IO instance Message-ID: <5ea8b888302e3_6167120888bc77322b0@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 8bb536e1 by Sylvain Henry at 2020-04-28T19:12:53-04:00 Document backpack fields in DynFlags - - - - - 5c1e0c68 by Sylvain Henry at 2020-04-28T19:12:53-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - efd2afc4 by Sylvain Henry at 2020-04-28T19:12:53-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 8683d6cf by Sylvain Henry at 2020-04-28T19:12:53-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - 4e32d8d8 by Sylvain Henry at 2020-04-28T19:12:53-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 306afb97 by Sylvain Henry at 2020-04-28T19:12:53-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 63a3d346 by Sylvain Henry at 2020-04-28T19:12:53-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 6dd3a77f by Simon Peyton Jones at 2020-04-28T19:12:54-04:00 Add tests for #17873 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47b2e1530fb0758de4b394f23da78c13b178e706...6dd3a77fa75f45f70d7364fceacdee5231e6d1b9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47b2e1530fb0758de4b394f23da78c13b178e706...6dd3a77fa75f45f70d7364fceacdee5231e6d1b9 You're receiving 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 29 04:43:18 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 29 Apr 2020 00:43:18 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Document backpack fields in DynFlags Message-ID: <5ea905e6d1254_6167120888bc77588a4@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 604c1bd2 by Sylvain Henry at 2020-04-29T00:43:12-04:00 Document backpack fields in DynFlags - - - - - d6849091 by Sylvain Henry at 2020-04-29T00:43:12-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 1a2a4aa3 by Sylvain Henry at 2020-04-29T00:43:12-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 3b3301d6 by Sylvain Henry at 2020-04-29T00:43:12-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - f08577d3 by Sylvain Henry at 2020-04-29T00:43:12-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - cd14b2dc by Sylvain Henry at 2020-04-29T00:43:12-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - ba652545 by Sylvain Henry at 2020-04-29T00:43:12-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - f7359b0e by Simon Peyton Jones at 2020-04-29T00:43:13-04:00 Add tests for #17873 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToByteCode.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6dd3a77fa75f45f70d7364fceacdee5231e6d1b9...f7359b0e60f12de50c430e1ace4a910f7d1b836b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6dd3a77fa75f45f70d7364fceacdee5231e6d1b9...f7359b0e60f12de50c430e1ace4a910f7d1b836b You're receiving 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 29 09:05:27 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 29 Apr 2020 05:05:27 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ea9435757241_6167e5b152c779237c@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 29280ad0 by Sebastian Graf at 2020-04-29T11:05:19+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29280ad0cea10f49cba9c6d2e944b92f41c421b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29280ad0cea10f49cba9c6d2e944b92f41c421b0 You're receiving 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 29 09:16:20 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 29 Apr 2020 05:16:20 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 4 commits: Define a Quote IO instance Message-ID: <5ea945e4db225_61673f81cd4c695c7792635@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 211bfb00 by Ömer Sinan Ağacan at 2020-04-29T11:34:08+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - d6aa2bf2 by Ömer Sinan Ağacan at 2020-04-29T12:15:50+03:00 Documentation and assertions - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56c776617b3a1493f604273e3f111a0641e749a1...d6aa2bf2cea3f9cf8f1d0ef467083983530523c3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56c776617b3a1493f604273e3f111a0641e749a1...d6aa2bf2cea3f9cf8f1d0ef467083983530523c3 You're receiving 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 29 09:19:40 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 29 Apr 2020 05:19:40 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Documentation and assertions Message-ID: <5ea946ac9627e_616711ab08a477934ac@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: c9d923b1 by Ömer Sinan Ağacan at 2020-04-29T12:19:31+03:00 Documentation and assertions - - - - - 5 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -623,7 +623,10 @@ toIfaceVar v --------------------- toIfaceLFInfo :: LambdaFormInfo -> IfaceLFInfo toIfaceLFInfo lfi = case lfi of - LFReEntrant _ _ arity _ _ -> + LFReEntrant top_lvl one_shot arity no_fvs _arg_descr -> + ASSERT(isTopLevel top_lvl) + ASSERT(one_shot == NoOneShotInfo) + ASSERT(no_fvs) IfLFReEntrant arity LFThunk _ _ updatable sfi mb_fun -> IfLFThunk updatable (toIfaceStandardFormInfo sfi) mb_fun ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -99,8 +99,11 @@ mkPartialIface hsc_env mod_details = mkIface_ hsc_env this_mod hsc_src used_th deps rdr_env fix_env warns hpc_info self_trust safe_mode usages doc_hdr decl_docs arg_docs mod_details --- | Fully instantiate a interface --- Adds fingerprints and potentially code generator produced information. +-- | Fully instantiate an interface. Adds fingerprints and potentially code +-- generator produced information. +-- +-- CgInfos is not available when not generating code (-fno-code), or when not +-- generating interface pragmas (-fomit-interface-pragmas). mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface mkFullIface hsc_env partial_iface mb_cg_infos = do let decls @@ -131,7 +134,7 @@ updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = = IfaceId nm ty details $ (if not_caffy then (HsNoCafRefs :) else id) (case mb_lf_info of - Nothing -> infos + Nothing -> infos -- LFInfos not available when building .cmm files Just lf_info -> HsLFInfo (toIfaceLFInfo lf_info) : infos) update_decl decl ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -391,7 +391,10 @@ data IfaceIdDetails -- omitted in this type. data IfaceLFInfo = IfLFReEntrant !RepArity - | IfLFThunk !Bool !IfaceStandardFormInfo !Bool + | IfLFThunk + !Bool -- True <=> updatable + !IfaceStandardFormInfo + !Bool -- True <=> might be a function type | IfLFCon !Name | IfLFUnknown !Bool | IfLFUnlifted ===================================== compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -40,7 +40,7 @@ updateModDetailsIdInfos _ cg_infos mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' cg_infos) type_env + ~type_env' = mapNameEnv (updateTyThingIdInfos type_env' cg_infos) type_env -- Not strict! !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts @@ -71,12 +71,12 @@ updateInstIdInfos type_env cg_infos = -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing +updateTyThingIdInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env cg_infos (AnId id) = +updateTyThingIdInfos type_env cg_infos (AnId id) = AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) -updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom +updateTyThingIdInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom -------------------------------------------------------------------------------- -- Unfoldings ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1504,6 +1504,18 @@ tcJoinInfo IfaceNotJoinPoint = Nothing tcLFInfo :: IfaceLFInfo -> IfL LambdaFormInfo tcLFInfo lfi = case lfi of IfLFReEntrant rep_arity -> + -- LFReEntrant closures in interface files are guaranteed to + -- + -- - Be top-level, as only top-level closures are exported. + -- - Be not one-shot, as top-level closures are never one-shot + -- - Have no free variables, as only non-top-level closures have free + -- variables + -- - Don't have ArgDescrs, as ArgDescr is used when generating code for + -- the closure + -- + -- These invariants are checked when generating the iface LFInfos in + -- toIfaceLFInfo in CoreToIface. + -- return (LFReEntrant TopLevel NoOneShotInfo rep_arity True ArgUnknown) IfLFThunk updatable sfi mb_fun -> View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9d923b1597486f87d379c7a4c8b1b8da12c84bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9d923b1597486f87d379c7a4c8b1b8da12c84bd You're receiving 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 29 10:17:09 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 29 Apr 2020 06:17:09 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Documentation Message-ID: <5ea9542511fba_61673f81cd4c695c78053ae@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 8049753a by Ömer Sinan Ağacan at 2020-04-29T13:16:57+03:00 Documentation - - - - - 3 changed files: - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/StgToCmm/Types.hs Changes: ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -103,7 +103,8 @@ mkPartialIface hsc_env mod_details -- generator produced information. -- -- CgInfos is not available when not generating code (-fno-code), or when not --- generating interface pragmas (-fomit-interface-pragmas). +-- generating interface pragmas (-fomit-interface-pragmas). See also +-- Note [Conveying CAF-info and LFInfo between modules] in GHC.StgToCmm.Types. mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface mkFullIface hsc_env partial_iface mb_cg_infos = do let decls ===================================== compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -21,7 +21,11 @@ import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class instances) +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class +-- instances). +-- +-- See Note [Conveying CAF-info and LFInfo between modules] in +-- GHC.StgToCmm.Types. updateModDetailsIdInfos :: DynFlags -> CgInfos ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -20,6 +20,50 @@ import GHC.Types.Name.Env import GHC.Types.Name.Set import GHC.Utils.Outputable +{- +Note [Conveying CAF-info and LFInfo between modules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some information about an Id is generated in the code generator, and is not +available earlier. Namely: + +* CAF info. Code motion in Cmm or earlier phases may move references around so + we compute information about which bits of code refer to which CAF late in the + Cmm pipeline. + +* LambdaFormInfo. This records the details of a closure representation, + including + - the final arity (for functions) + - whether it is a data constructor, and if so its tag + +Collectively we call this CgInfo (see GHC.StgToCmm.Types). + +It's very useful for importing modules to have this information. We can always +make a conservative assumption, but that is bad: e.g. + +* For CAF info, if we know nothing we have to assume it is a CAF which bloats + the SRTs of the importing module. + +- For data constructors, we really like having well-tagged pointers. See #14677, + #16559, #15155, and wiki: commentary/rts/haskell-execution/pointer-tagging + +So we arrange to always serialise this information into the interface file. The +moving parts are: + +* We record the CgInfo in the IdInfo of the Id. + +* GHC.Driver.Pipeline: the call to updateModDetailsIdInfos augments the + ModDetails constructed at the end of the Core pipeline, with with CgInfo + gleaned from the back end. The hard work is done in GHC.Iface.UpdateIdInfos. + +* For ModIface we generate the final ModIface with CgInfo in + GHC.Iface.Make.mkFullIface. + +* We don't absolutely guarantee to serialise the CgInfo: we won't if you have + -fomit-interface-pragmas or -fno-code; and we won't read it in if you have + -fignore-interface-pragmas. (We could revisit this decision.) +-} + -- | Codegen-generated Id infos, to be passed to downstream via interfaces. -- -- This stuff is for optimization purposes only, they're not compulsory. @@ -29,6 +73,8 @@ import GHC.Utils.Outputable -- `LFUnknown True` (which just says "it could be anything" and we do slow -- entry). -- +-- See also Note [Conveying CAF-info and LFInfo between modules] above. +-- data CgInfos = CgInfos { cgNonCafs :: !NameSet -- ^ Exported Non-CAFFY closures in the current module. Everything else is View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8049753a33c9bd0879b8c11af8ae315b7e1072ba -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8049753a33c9bd0879b8c11af8ae315b7e1072ba You're receiving 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 29 10:32:21 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 29 Apr 2020 06:32:21 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ea957b561f85_61673f81cc913ba07807769@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 893a9737 by Sebastian Graf at 2020-04-29T12:32:14+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/893a9737fcda41bbb3b19a2517559008da6fb9a3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/893a9737fcda41bbb3b19a2517559008da6fb9a3 You're receiving 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 29 13:08:33 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 29 Apr 2020 09:08:33 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18098 Message-ID: <5ea97c51d8aff_61673f81cd9bfa6c7827251@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18098 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18098 You're receiving 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 29 14:02:28 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 29 Apr 2020 10:02:28 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 3 commits: Accept two more changed test outputs Message-ID: <5ea988f4d8531_616787c09cc7854058@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: fe309b07 by Sebastian Graf at 2020-04-27T12:46:41+02:00 Accept two more changed test outputs - - - - - 0f2dc7d4 by Sebastian Graf at 2020-04-29T16:01:40+02:00 Update CaseBinderCPR with a new function - - - - - e64516e7 by Sebastian Graf at 2020-04-29T16:02:23+02:00 Don't give the case binder the CPR property - - - - - 6 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Types/Cpr.hs - testsuite/tests/cpranal/sigs/CaseBinderCPR.hs - testsuite/tests/cpranal/sigs/CaseBinderCPR.stderr - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -27,13 +27,12 @@ import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info import GHC.Core.Utils ( exprIsHNF, dumpIdInfoOfProgram ) -import GHC.Core.TyCon import GHC.Core.Type import GHC.Core.FamInstEnv import GHC.Core.Opt.WorkWrap.Utils import Util import ErrUtils ( dumpIfSet_dyn, DumpFormat (..) ) -import Maybes ( isJust, isNothing ) +import Maybes ( isNothing ) {- Note [Constructed Product Result] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -205,10 +204,8 @@ cprAnal' env args (Case scrut case_bndr ty alts) -- head strictness. (scrut_ty, scrut') = cprAnal env [] scrut (whnf_flag, case_bndr_ty) = forceCprTy (getStrDmd seqDmd) scrut_ty - -- Regardless of whether scrut had the CPR property or not, the case binder - -- certainly has it. See 'extendEnvForDataAlt'. - (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args case_bndr case_bndr_ty) alts - res_ty = lubCprTypes alt_tys `bothCprType` whnf_flag + (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args case_bndr case_bndr_ty) alts + res_ty = lubCprTypes alt_tys `bothCprType` whnf_flag cprAnal' env args (Let (NonRec id rhs) body) = (body_ty, Let (NonRec id' rhs') body') @@ -477,19 +474,10 @@ nonVirgin env = env { ae_virgin = False } extendEnvForDataAlt :: AnalEnv -> Id -> CprType -> DataCon -> [Var] -> AnalEnv -- See Note [CPR in a DataAlt case alternative] extendEnvForDataAlt env case_bndr case_bndr_ty dc bndrs - = extendAnalEnv env' case_bndr (CprSig case_bndr_ty') + = extendAnalEnv env' case_bndr (CprSig case_bndr_ty) where - tycon = dataConTyCon dc - is_product = isJust (isDataProductTyCon_maybe tycon) - is_sum = isJust (isDataSumTyCon_maybe tycon) - case_bndr_ty' - | is_product || is_sum = markConCprType dc case_bndr_ty - -- Any of the constructors had existentials. This is a little too - -- conservative (after all, we only care about the particular data con), - -- but there is no easy way to write is_sum and this won't happen much. - | otherwise = case_bndr_ty env' - | Just fields <- splitConCprTy dc case_bndr_ty' + | Just fields <- splitConCprTy dc case_bndr_ty , let ids = filter isId bndrs , let cpr_tys = map (CprSig . CprType 0) fields = extendAnalEnvList env (zipEqual "extendEnvForDataAlt" ids cpr_tys) ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Types.Cpr ( TerminationFlag (Terminates), Cpr, topCpr, conCpr, whnfTermCpr, divergeCpr, lubCpr, asConCpr, CprType (..), topCprType, whnfTermCprType, conCprType, lubCprType, lubCprTypes, - pruneDeepCpr, markConCprType, splitConCprTy, applyCprTy, abstractCprTy, + pruneDeepCpr, splitConCprTy, applyCprTy, abstractCprTy, abstractCprTyNTimes, ensureCprTyArity, trimCprTy, forceCprTy, forceCpr, bothCprType, cprTransformDataConSig, UnboxingStrategy, cprTransformSig, argCprTypesFromStrictSig, @@ -303,21 +303,6 @@ conCprType con_tag args = CprType 0 (conCpr con_tag cprs) where cprs = extractArgCprAndTermination args -markConCprType :: DataCon -> CprType -> CprType -markConCprType dc _ty@(CprType n cpr) - = ASSERT2( n == 0, ppr _ty ) CprType 0 (conCpr con_tag fields) - where - con_tag = dataConTag dc - wkr_arity = dataConRepArity dc - fields = case cpr of - NoMoreCpr (Term _ (Levitate (Con t terms))) - | con_tag == t -> map NoMoreCpr terms - NoMoreCpr (Term _ Bot) -> replicate wkr_arity (NoMoreCpr botTerm) - Cpr _ (Levitate (Con t cprs)) - | con_tag == t -> cprs - Cpr _ Bot -> replicate wkr_arity botCpr - _ -> replicate wkr_arity topCpr - splitConCprTy :: DataCon -> CprType -> Maybe [Cpr] splitConCprTy dc (CprType 0 (Cpr _ l)) | Bot <- l ===================================== testsuite/tests/cpranal/sigs/CaseBinderCPR.hs ===================================== @@ -13,3 +13,9 @@ f_list_cmp a_cmp (a_x:a_xs) (a_y:a_ys)= else r_order where r_order = a_cmp a_x a_y + + +-- But not every case binder has the CPR property. +-- x below does not and we should not CPR nestedly for it: +g :: [Int] -> (Int, Int) +g xs = let x = xs !! 0 in x `seq` (x, x) ===================================== testsuite/tests/cpranal/sigs/CaseBinderCPR.stderr ===================================== @@ -2,5 +2,6 @@ ==================== Cpr signatures ==================== CaseBinderCPR.$trModule: #c1(#c1(#), #c1(#)) CaseBinderCPR.f_list_cmp: *c1(*) +CaseBinderCPR.g: *c1(#, #) ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -7,7 +7,7 @@ Result size of Tidy Core T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, - Cpr=#c1(), + Cpr=#c1(*), Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=False) ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -9,6 +9,7 @@ T7360.$WFoo3 [InlPrag=INLINE[0] CONLIKE] :: Int -> Foo Arity=1, Caf=NoCafRefs, Str=, + Cpr=#c3(*), Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9acac76afc7ab639d60742c4a650de62a3be8860...e64516e7a710c7402660b9a05bdf97fa8f7d5134 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9acac76afc7ab639d60742c4a650de62a3be8860...e64516e7a710c7402660b9a05bdf97fa8f7d5134 You're receiving 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 29 14:20:07 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 29 Apr 2020 10:20:07 -0400 Subject: [Git][ghc/ghc][wip/T18098] Mark rule args as non-tail-called Message-ID: <5ea98d1788db6_6167e5b152c785621d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18098 at Glasgow Haskell Compiler / GHC Commits: 375769d2 by Simon Peyton Jones at 2020-04-29T15:19:18+01:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 5 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Types/Basic.hs - + testsuite/tests/simplCore/should_compile/T18098.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -728,7 +728,7 @@ a right-hand side. In particular, we need to a) call 'markAllInsideLam' *unless* the binding is for a thunk, a one-shot lambda, or a non-recursive join point; and - b) call 'markAllNonTailCalled' *unless* the binding is for a join point. + b) call 'markAllNonTail' *unless* the binding is for a join point. Some examples, with how the free occurrences in e (assumed not to be a value lambda) get marked: @@ -1605,7 +1605,7 @@ occAnalUnfolding env mb_join_arity unf where env' = env `addInScope` bndrs (usage, args') = occAnalList env' args - final_usage = zapDetails (delDetailsList usage bndrs) + final_usage = markAllManyNonTail (delDetailsList usage bndrs) unf -> (emptyDetails, unf) @@ -1626,13 +1626,13 @@ occAnalRules env mb_join_arity bndr | otherwise = rule { ru_args = args', ru_rhs = rhs' } (lhs_uds, args') = occAnalList env' args - lhs_uds' = markAllMany $ + lhs_uds' = markAllManyNonTail $ lhs_uds `delDetailsList` bndrs (rhs_uds, rhs') = occAnal env' rhs -- Note [Rules are extra RHSs] -- Note [Rule dependency info] - rhs_uds' = markAllNonTailCalledIf (not exact_join) $ + rhs_uds' = markAllNonTailIf (not exact_join) $ markAllMany $ rhs_uds `delDetailsList` bndrs @@ -1758,7 +1758,7 @@ occAnal env (Tick tickish body) -- not the end of the world. | tickish `tickishScopesLike` SoftScope - = (markAllNonTailCalled usage, Tick tickish body') + = (markAllNonTail usage, Tick tickish body') | Breakpoint _ ids <- tickish = (usage_lam `andUDs` foldr addManyOcc emptyDetails ids, Tick tickish body') @@ -1769,7 +1769,7 @@ occAnal env (Tick tickish body) where !(usage,body') = occAnal env body -- for a non-soft tick scope, we can inline lambdas only - usage_lam = markAllNonTailCalled (markAllInsideLam usage) + usage_lam = markAllNonTail (markAllInsideLam usage) -- TODO There may be ways to make ticks and join points play -- nicer together, but right now there are problems: -- let j x = ... in tick (j 1) @@ -1780,13 +1780,13 @@ occAnal env (Tick tickish body) occAnal env (Cast expr co) = case occAnal env expr of { (usage, expr') -> - let usage1 = zapDetailsIf (isRhsEnv env) usage + let usage1 = markAllManyNonTailIf (isRhsEnv env) usage -- usage1: if we see let x = y `cast` co -- then mark y as 'Many' so that we don't -- immediately inline y again. usage2 = addManyOccs usage1 (coVarsOfCo co) -- usage2: see Note [Gather occurrences of coercion variables] - in (markAllNonTailCalled usage2, Cast expr' co) + in (markAllNonTail usage2, Cast expr' co) } occAnal env app@(App _ _) @@ -1799,7 +1799,7 @@ occAnal env app@(App _ _) occAnal env (Lam x body) | isTyVar x = case occAnal env body of { (body_usage, body') -> - (markAllNonTailCalled body_usage, Lam x body') + (markAllNonTail body_usage, Lam x body') } -- For value lambdas we do a special hack. Consider @@ -1815,7 +1815,7 @@ occAnal env expr@(Lam _ _) = case occAnalLamOrRhs env bndrs body of { (usage, tagged_bndrs, body') -> let expr' = mkLams tagged_bndrs body' - usage1 = markAllNonTailCalled usage + usage1 = markAllNonTail usage one_shot_gp = all isOneShotBndr tagged_bndrs final_usage = markAllInsideLamIf (not one_shot_gp) usage1 in @@ -1832,7 +1832,7 @@ occAnal env (Case scrut bndr ty alts) let alts_usage = foldr orUDs emptyDetails alts_usage_s (alts_usage1, tagged_bndr) = tagLamBinder alts_usage bndr - total_usage = markAllNonTailCalled scrut_usage `andUDs` alts_usage1 + total_usage = markAllNonTail scrut_usage `andUDs` alts_usage1 -- Alts can have tail calls, but the scrutinee can't in total_usage `seq` (total_usage, Case scrut' tagged_bndr ty alts') }} @@ -1893,7 +1893,7 @@ occAnalApp env (Var fun, args, ticks) all_uds = fun_uds `andUDs` final_args_uds !(args_uds, args') = occAnalArgs env args one_shots - !final_args_uds = markAllNonTailCalled $ + !final_args_uds = markAllNonTail $ markAllInsideLamIf (isRhsEnv env && is_exp) $ args_uds -- We mark the free vars of the argument of a constructor or PAP @@ -1923,7 +1923,7 @@ occAnalApp env (Var fun, args, ticks) -- See Note [Sources of one-shot information], bullet point A'] occAnalApp env (fun, args, ticks) - = (markAllNonTailCalled (fun_uds `andUDs` args_uds), + = (markAllNonTail (fun_uds `andUDs` args_uds), mkTicks ticks $ mkApps fun' args') where !(fun_uds, fun') = occAnal (addAppCtxt env args) fun @@ -2526,7 +2526,7 @@ data UsageDetails = UD { ud_env :: !OccInfoEnv , ud_z_many :: ZappedSet -- apply 'markMany' to these , ud_z_in_lam :: ZappedSet -- apply 'markInsideLam' to these - , ud_z_no_tail :: ZappedSet } -- apply 'markNonTailCalled' to these + , ud_z_no_tail :: ZappedSet } -- apply 'markNonTail' to these -- INVARIANT: All three zapped sets are subsets of the OccInfoEnv instance Outputable UsageDetails where @@ -2587,28 +2587,28 @@ emptyDetails = UD { ud_env = emptyVarEnv isEmptyDetails :: UsageDetails -> Bool isEmptyDetails = isEmptyVarEnv . ud_env -markAllMany, markAllInsideLam, markAllNonTailCalled, zapDetails +markAllMany, markAllInsideLam, markAllNonTail, markAllManyNonTail :: UsageDetails -> UsageDetails markAllMany ud = ud { ud_z_many = ud_env ud } markAllInsideLam ud = ud { ud_z_in_lam = ud_env ud } -markAllNonTailCalled ud = ud { ud_z_no_tail = ud_env ud } +markAllNonTail ud = ud { ud_z_no_tail = ud_env ud } -markAllInsideLamIf, markAllNonTailCalledIf :: Bool -> UsageDetails -> UsageDetails +markAllInsideLamIf, markAllNonTailIf :: Bool -> UsageDetails -> UsageDetails markAllInsideLamIf True ud = markAllInsideLam ud markAllInsideLamIf False ud = ud -markAllNonTailCalledIf True ud = markAllNonTailCalled ud -markAllNonTailCalledIf False ud = ud +markAllNonTailIf True ud = markAllNonTail ud +markAllNonTailIf False ud = ud -zapDetails = markAllMany . markAllNonTailCalled -- effectively sets to noOccInfo +markAllManyNonTail = markAllMany . markAllNonTail -- effectively sets to noOccInfo -zapDetailsIf :: Bool -- If this is true - -> UsageDetails -- Then do zapDetails on this +markAllManyNonTailIf :: Bool -- If this is true + -> UsageDetails -- Then do markAllManyNonTail on this -> UsageDetails -zapDetailsIf True uds = zapDetails uds -zapDetailsIf False uds = uds +markAllManyNonTailIf True uds = markAllManyNonTail uds +markAllManyNonTailIf False uds = uds lookupDetails :: UsageDetails -> Id -> OccInfo lookupDetails ud id @@ -2674,7 +2674,7 @@ doZappingByUnique (UD { ud_z_many = many occ1 | uniq `elemVarEnvByKey` many = markMany occ | uniq `elemVarEnvByKey` in_lam = markInsideLam occ | otherwise = occ - occ2 | uniq `elemVarEnvByKey` no_tail = markNonTailCalled occ1 + occ2 | uniq `elemVarEnvByKey` no_tail = markNonTail occ1 | otherwise = occ1 alterZappedSets :: UsageDetails -> (ZappedSet -> ZappedSet) -> UsageDetails @@ -2700,7 +2700,7 @@ adjustRhsUsage :: Maybe JoinArity -> RecFlag -> UsageDetails adjustRhsUsage mb_join_arity rec_flag bndrs usage = markAllInsideLamIf (not one_shot) $ - markAllNonTailCalledIf (not exact_join) $ + markAllNonTailIf (not exact_join) $ usage where one_shot = case mb_join_arity of @@ -2738,7 +2738,7 @@ tagLamBinder usage bndr = (usage2, bndr') where occ = lookupDetails usage bndr - bndr' = setBinderOcc (markNonTailCalled occ) bndr + bndr' = setBinderOcc (markNonTail occ) bndr -- Don't try to make an argument into a join point usage1 = usage `delDetails` bndr usage2 | isId bndr = addManyOccs usage1 (idUnfoldingVars bndr) @@ -2759,7 +2759,7 @@ tagNonRecBinder lvl usage binder will_be_join = decideJoinPointHood lvl usage [binder] occ' | will_be_join = -- must already be marked AlwaysTailCalled ASSERT(isAlwaysTailCalled occ) occ - | otherwise = markNonTailCalled occ + | otherwise = markNonTail occ binder' = setBinderOcc occ' binder usage' = usage `delDetails` binder in @@ -2930,7 +2930,7 @@ See Invariant 2a of Note [Invariants on join points] in GHC.Core ************************************************************************ -} -markMany, markInsideLam, markNonTailCalled :: OccInfo -> OccInfo +markMany, markInsideLam, markNonTail :: OccInfo -> OccInfo markMany IAmDead = IAmDead markMany occ = ManyOccs { occ_tail = occ_tail occ } @@ -2938,8 +2938,8 @@ markMany occ = ManyOccs { occ_tail = occ_tail occ } markInsideLam occ@(OneOcc {}) = occ { occ_in_lam = IsInsideLam } markInsideLam occ = occ -markNonTailCalled IAmDead = IAmDead -markNonTailCalled occ = occ { occ_tail = NoTailCallInfo } +markNonTail IAmDead = IAmDead +markNonTail occ = occ { occ_tail = NoTailCallInfo } addOccInfo, orOccInfo :: OccInfo -> OccInfo -> OccInfo ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -446,7 +446,7 @@ pprIdBndrInfo info lbv_info = oneShotInfo info has_prag = not (isDefaultInlinePragma prag_info) - has_occ = not (isManyOccs occ_info) + has_occ = not (isNoOccInfo occ_info) has_dmd = not $ isTopDmd dmd_info has_lbv = not (hasNoOneShotInfo lbv_info) ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -67,7 +67,7 @@ module GHC.Types.Basic ( OccInfo(..), noOccInfo, seqOccInfo, zapFragileOcc, isOneOcc, isDeadOcc, isStrongLoopBreaker, isWeakLoopBreaker, isManyOccs, - strongLoopBreaker, weakLoopBreaker, + isNoOccInfo, strongLoopBreaker, weakLoopBreaker, InsideLam(..), OneBranch(..), @@ -958,6 +958,10 @@ See OccurAnal Note [Weak loop breakers] noOccInfo :: OccInfo noOccInfo = ManyOccs { occ_tail = NoTailCallInfo } +isNoOccInfo :: OccInfo -> Bool +isNoOccInfo ManyOccs { occ_tail = NoTailCallInfo } = True +isNoOccInfo _ = False + isManyOccs :: OccInfo -> Bool isManyOccs ManyOccs{} = True isManyOccs _ = False ===================================== testsuite/tests/simplCore/should_compile/T18098.hs ===================================== @@ -0,0 +1,78 @@ +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE KindSignatures #-} +module Bug where + +import Control.Monad.ST (runST, ST) +import Data.Kind (Type) +import Data.Functor.Identity (Identity(..)) + +gcons :: (GVector v a) => a -> Stream Identity (Chunk v a) -> v a +gcons x tb = gmvmunstreamUnknown $ sappend (ssingleton x) tb +{-# INLINE gcons #-} + +data Chunk v a = MkChunk (forall s. GVector v a => Mutable v s a -> ST s ()) + +data Step s a = Yield a s | Done + +data Stream m a = forall s. Stream (s -> m (Step s a)) s + +data Mutable :: (Type -> Type) -> Type -> Type -> Type + +class GVector v a where + gmbasicLength :: Mutable v s a -> Int + gmbasicUnsafeSlice :: Mutable v s a -> Mutable v s a + gmbasicUnsafeNew :: ST s (Mutable v s a) + gmbasicUnsafeWrite :: a -> Mutable v s a -> ST s () + gmbasicUnsafeGrow :: Mutable v s a -> Int -> m (Mutable v s a) + gbasicUnsafeFreeze :: Mutable v s a -> ST s (v a) + +sfoldlM :: (a -> b -> ST s a) -> (t -> Step t b) -> a -> t -> ST s a +sfoldlM m step = foldlM_loop + where + foldlM_loop z s + = case step s of + Yield x s' -> do { z' <- m z x; foldlM_loop z' s' } + Done -> return z +{-# INLINE [1] sfoldlM #-} + +sappend :: Stream Identity a -> Stream Identity a -> Stream Identity a +Stream stepa ta `sappend` Stream stepb _ = Stream step (Left ta) + where + {-# INLINE [0] step #-} + step (Left sa) = do + r <- stepa sa + return $ case r of + Yield x _ -> Yield x (Left sa) + Done -> Done + step (Right sb) = do + r <- stepb sb + return $ case r of + Yield x _ -> Yield x (Right sb) + Done -> Done +{-# INLINE [1] sappend #-} + +ssingleton :: Monad m => a -> Stream m (Chunk v a) +ssingleton x = Stream (return . step) True + where + {-# INLINE [0] step #-} + step True = Yield (MkChunk (gmbasicUnsafeWrite x)) False + step False = Done +{-# INLINE [1] ssingleton #-} + +gmvmunstreamUnknown :: GVector v a => Stream Identity (Chunk v a) -> v a +gmvmunstreamUnknown (Stream vstep u) + = runST (do + v <- gmbasicUnsafeNew + sfoldlM copyChunk (runIdentity . vstep) (v,0) u + gbasicUnsafeFreeze v) + where + {-# INLINE [0] copyChunk #-} + copyChunk (v,i) (MkChunk f) + = do + v' <- gmbasicUnsafeGrow v (gmbasicLength v) + f (gmbasicUnsafeSlice v') + return (v',i) +{-# INLINE gmvmunstreamUnknown #-} ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -317,3 +317,4 @@ test('T17966', # NB: T17810: -fspecialise-aggressively test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) +test('T18098', normal, compile, ['-dcore-lint -O2']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/375769d212839751356455a22535f6162877339b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/375769d212839751356455a22535f6162877339b You're receiving 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 29 15:11:08 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 29 Apr 2020 11:11:08 -0400 Subject: [Git][ghc/ghc][wip/T18049] 2 commits: PmCheck: Only call checkSingle if we would report warnings Message-ID: <5ea9990c2c29_61673f81cc913ba078610fc@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18049 at Glasgow Haskell Compiler / GHC Commits: 5775abc4 by Sebastian Graf at 2020-04-29T16:47:59+02:00 PmCheck: Only call checkSingle if we would report warnings - - - - - d246cb9a by Sebastian Graf at 2020-04-29T17:10:22+02:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` and `WpLet` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Tc/Types/Evidence.hs - + testsuite/tests/pmcheck/should_compile/T18049.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -33,7 +33,7 @@ import {-# SOURCE #-} GHC.HsToCore.Match ( matchWrapper ) import GHC.HsToCore.Monad import GHC.HsToCore.GuardedRHSs import GHC.HsToCore.Utils -import GHC.HsToCore.PmCheck ( needToRunPmCheck, addTyCsDs, checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Hs -- lots of things import GHC.Core -- lots of things @@ -145,12 +145,20 @@ dsHsBind dflags (VarBind { var_id = var else [] ; return (force_var, [core_bind]) } -dsHsBind dflags b@(FunBind { fun_id = L _ fun +dsHsBind dflags b@(FunBind { fun_id = L loc fun , fun_matches = matches , fun_ext = co_fn , fun_tick = tick }) - = do { (args, body) <- matchWrapper - (mkPrefixFunRhs (noLoc $ idName fun)) + = do { (args, body) <- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + -- FromSource might not be accurate (we don't have any + -- origin annotations for things in this module), but at + -- worst we do superfluous calls to the pattern match + -- oracle. + -- addTyCsDs: Add type evidence to the refinement type + -- predicate of the coverage checker + -- See Note [Type and Term Equality Propagation] in PmCheck + matchWrapper + (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body @@ -189,15 +197,7 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts , abs_exports = exports , abs_ev_binds = ev_binds , abs_binds = binds, abs_sig = has_sig }) - = do { ds_binds <- applyWhen (needToRunPmCheck dflags FromSource) - -- FromSource might not be accurate, but at worst - -- we do superfluous calls to the pattern match - -- oracle. - -- addTyCsDs: push type constraints deeper - -- for inner pattern match check - -- See Check, Note [Type and Term Equality Propagation] - (addTyCsDs (listToBag dicts)) - (dsLHsBinds binds) + = do { ds_binds <- addTyCsDs FromSource (listToBag dicts) (dsLHsBinds binds) ; ds_ev_binds <- dsTcEvBinds_s ev_binds @@ -206,7 +206,6 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind" - ----------------------- dsAbsBinds :: DynFlags -> [TyVar] -> [EvVar] -> [ABExport GhcTc] ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.HsToCore.ListComp import GHC.HsToCore.Utils import GHC.HsToCore.Arrows import GHC.HsToCore.Monad -import GHC.HsToCore.PmCheck ( checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Types.Name import GHC.Types.Name.Env import GHC.Core.FamInstEnv( topNormaliseType ) @@ -280,7 +280,8 @@ dsExpr hswrap@(XExpr (HsWrap co_fn e)) HsConLikeOut _ (RealDataCon dc) -> return $ varToCoreExpr (dataConWrapId dc) XExpr (HsWrap _ _) -> pprPanic "dsExpr: HsWrap inside HsWrap" (ppr hswrap) HsPar _ _ -> pprPanic "dsExpr: HsPar inside HsWrap" (ppr hswrap) - _ -> dsExpr e + _ -> addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + dsExpr e -- See Note [Detecting forced eta expansion] ; wrap' <- dsHsWrapper co_fn ; dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -859,8 +859,10 @@ matchSinglePatVar var ctx pat ty match_result do { dflags <- getDynFlags ; locn <- getSrcSpanDs - -- Pattern match check warnings - ; checkSingle dflags (DsMatchContext ctx locn) var (unLoc pat) + -- Pattern match check warnings + ; if isMatchContextPmChecked dflags FromSource ctx + then checkSingle dflags (DsMatchContext ctx locn) var (unLoc pat) + else pure () ; let eqn_info = EqnInfo { eqn_pats = [unLoc (decideBangHood dflags pat)] , eqn_orig = FromSource ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -14,7 +14,7 @@ Pattern Matching Coverage Checking. module GHC.HsToCore.PmCheck ( -- Checking and printing checkSingle, checkMatches, checkGuardMatches, - needToRunPmCheck, isMatchContextPmChecked, + isMatchContextPmChecked, -- See Note [Type and Term Equality Propagation] addTyCsDs, addScrutTmCs @@ -45,7 +45,7 @@ import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Types.Var (EvVar) import GHC.Core.Coercion -import GHC.Tc.Types.Evidence ( HsWrapper(..), isIdHsWrapper ) +import GHC.Tc.Types.Evidence (HsWrapper(..), isIdHsWrapper) import GHC.Tc.Utils.TcType (evVarPred) import {-# SOURCE #-} GHC.HsToCore.Expr (dsExpr, dsLExpr, dsSyntaxExpr) import {-# SOURCE #-} GHC.HsToCore.Binds (dsHsWrapper) @@ -53,6 +53,7 @@ import GHC.HsToCore.Utils (selectMatchVar) import GHC.HsToCore.Match.Literal (dsLit, dsOverLit) import GHC.HsToCore.Monad import GHC.Data.Bag +import GHC.Data.IOEnv (unsafeInterleaveM) import GHC.Data.OrdList import GHC.Core.TyCo.Rep import GHC.Core.Type @@ -1033,20 +1034,30 @@ Functions `addScrutTmCs' is responsible for generating these constraints. -} +-- | Locally update 'dsl_deltas' with the given action, but defer evaluation +-- with 'unsafeInterleaveM' in order not to do unnecessary work. locallyExtendPmDelta :: (Deltas -> DsM Deltas) -> DsM a -> DsM a -locallyExtendPmDelta ext k = getPmDeltas >>= ext >>= \deltas -> do - inh <- isInhabited deltas - -- If adding a constraint would lead to a contradiction, don't add it. - -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ - -- for why this is done. - if inh - then updPmDeltas deltas k - else k - --- | Add in-scope type constraints -addTyCsDs :: Bag EvVar -> DsM a -> DsM a -addTyCsDs ev_vars = - locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars)) +locallyExtendPmDelta ext k = do + deltas <- getPmDeltas + deltas' <- unsafeInterleaveM $ do + deltas' <- ext deltas + inh <- isInhabited deltas + -- If adding a constraint would lead to a contradiction, don't add it. + -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ + -- for why this is done. + if inh + then pure deltas' + else pure deltas + updPmDeltas deltas' k + +-- | Add in-scope type constraints if the coverage checker might run and then +-- run the given action. +addTyCsDs :: Origin -> Bag EvVar -> DsM a -> DsM a +addTyCsDs origin ev_vars m = do + dflags <- getDynFlags + applyWhen (needToRunPmCheck dflags origin) + (locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars))) + m -- | Add equalities for the scrutinee to the local 'DsM' environment when -- checking a case expression: ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -10,7 +10,7 @@ module GHC.Tc.Types.Evidence ( (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, - pprHsWrapper, + pprHsWrapper, hsWrapDictBinders, -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), @@ -370,6 +370,25 @@ isErasableHsWrapper = go go WpTyApp{} = True go WpLet{} = False +hsWrapDictBinders :: HsWrapper -> Bag DictId +-- Collects the given dict Ids, bound by the wrapper, +-- that scope over the "hole" in the wrapper +hsWrapDictBinders wrap = go wrap emptyBag + where + go WpHole acc = acc + go (w1 `WpCompose` w2) acc = go w1 (go w2 acc) + go (WpFun _ w2 _ _) acc = go w2 acc + go (WpCast {}) acc = acc + go (WpEvLam dict_id) acc = dict_id `consBag` acc + go (WpEvApp {}) acc = acc + go (WpTyLam {}) acc = acc + go (WpTyApp {}) acc = acc + go (WpLet binds) acc = go_binds binds `unionBags` acc + + go_binds (EvBinds bs) = mapBag eb_lhs bs + go_binds (TcEvBinds ebv) = pprPanic "hsWrapperDictBinds" (ppr ebv) + -- Should only be applied post zonking + collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, -- stopping as soon as you get to a non-lambda binder ===================================== testsuite/tests/pmcheck/should_compile/T18049.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +module Bug where + +import Data.Kind + +data SBool :: Bool -> Type where + SFalse :: SBool False + STrue :: SBool True + +f :: SBool b + -> (b ~ True => SBool b -> r) + -> (b ~ False => SBool b -> r) + -> r +f x t f = + case x of + SFalse -> f x + STrue -> t x + +g :: forall b. SBool b -> () +g x = f x + (\x' -> + case x' of + -- SFalse -> () + STrue -> ()) + (\_ -> ()) ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -118,6 +118,8 @@ test('T17977', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17977b', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T18049', normal, compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d866e11829e223523d526e2bc998d6df22c36a2e...d246cb9a88523f247e8a96cc3b710cadc3c59e2d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d866e11829e223523d526e2bc998d6df22c36a2e...d246cb9a88523f247e8a96cc3b710cadc3c59e2d You're receiving 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 29 15:52:04 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Wed, 29 Apr 2020 11:52:04 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/hadrian-multi-comp Message-ID: <5ea9a2a432287_6167122e22ac786842a@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/hadrian-multi-comp at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/hadrian-multi-comp You're receiving 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 29 16:24:34 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Wed, 29 Apr 2020 12:24:34 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/hole-refactor Message-ID: <5ea9aa4290ef8_6167e5b152c78802ae@gitlab.haskell.org.mail> Richard Eisenberg pushed new branch wip/hole-refactor at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/hole-refactor You're receiving 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 29 16:33:39 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 29 Apr 2020 12:33:39 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17609 Message-ID: <5ea9ac63b59c8_616711ab08a4788652@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T17609 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17609 You're receiving 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 29 16:36:00 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 29 Apr 2020 12:36:00 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ea9acf0cd1ed_61673f81cd4c695c7888377@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: a46287e3 by Sebastian Graf at 2020-04-29T18:35:52+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a46287e3792426f2c07d2c96b1cc273267ae542f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a46287e3792426f2c07d2c96b1cc273267ae542f You're receiving 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 29 16:46:36 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 29 Apr 2020 12:46:36 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Document backpack fields in DynFlags Message-ID: <5ea9af6c48e9c_616711ab08a478976d3@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 91d458a0 by Sylvain Henry at 2020-04-29T12:46:09-04:00 Document backpack fields in DynFlags - - - - - 4d8eecce by Sylvain Henry at 2020-04-29T12:46:09-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 906142ca by Sylvain Henry at 2020-04-29T12:46:09-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 672ad357 by Sylvain Henry at 2020-04-29T12:46:09-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - 20afdab9 by Sylvain Henry at 2020-04-29T12:46:09-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 0540b931 by Sylvain Henry at 2020-04-29T12:46:10-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8de95ac0 by Sylvain Henry at 2020-04-29T12:46:10-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - a274650d by Alexis King at 2020-04-29T12:46:27-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - de2aea4a by Alexis King at 2020-04-29T12:46:27-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - b3c7a817 by Alexis King at 2020-04-29T12:46:28-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - b21d26e7 by Simon Peyton Jones at 2020-04-29T12:46:29-04:00 Add tests for #17873 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToByteCode.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7359b0e60f12de50c430e1ace4a910f7d1b836b...b21d26e7143f7b0df675a5d01b8ac6b8d5adb916 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7359b0e60f12de50c430e1ace4a910f7d1b836b...b21d26e7143f7b0df675a5d01b8ac6b8d5adb916 You're receiving 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 29 16:48:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 29 Apr 2020 12:48:03 -0400 Subject: [Git][ghc/ghc][wip/T17609] nativeGen: Deduplicate DWARF strings Message-ID: <5ea9afc3e1de7_6167c5ce1b07903639@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17609 at Glasgow Haskell Compiler / GHC Commits: 66e11eff by Ben Gamari at 2020-04-29T12:47:50-04:00 nativeGen: Deduplicate DWARF strings As noted in #17609, we previously made no attempt to deduplicate strings. This resulted in unnecessarily long compile times and large object files. Fix this. Fixes #17609. - - - - - 2 changed files: - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Dwarf/Types.hs Changes: ===================================== compiler/GHC/CmmToAsm/Dwarf.hs ===================================== @@ -47,11 +47,12 @@ dwarfGen df modLoc us blocks = do compPath <- getCurrentDirectory let lowLabel = dblCLabel $ head procs highLabel = mkAsmTempEndLabel $ dblCLabel $ last procs + producer = dwarfStringFromString $ cProjectName ++ " " ++ cProjectVersion dwarfUnit = DwarfCompileUnit { dwChildren = map (procToDwarf df) (map stripBlocks procs) , dwName = fromMaybe "" (ml_hs_file modLoc) - , dwCompDir = addTrailingPathSeparator compPath - , dwProducer = cProjectName ++ " " ++ cProjectVersion + , dwCompDir = dwarfStringFromString $ addTrailingPathSeparator compPath + , dwProducer = producer , dwLowLabel = lowLabel , dwHighLabel = highLabel , dwLineLabel = dwarfLineLabel @@ -77,6 +78,9 @@ dwarfGen df modLoc us blocks = do , compileUnitFooter unitU ] + -- .debug_str section: Strings + let stringsSct = dwarfStringsSection (dwarfInfoStrings dwarfUnit) + -- .debug_line section: Generated mainly by the assembler, but we -- need to label it let lineSct = dwarfLineSection platform $$ @@ -93,7 +97,7 @@ dwarfGen df modLoc us blocks = do | otherwise = [DwarfARange lowLabel highLabel] let aranges = dwarfARangesSection platform $$ pprDwarfARanges platform aranges' unitU - return (infoSct $$ abbrevSct $$ lineSct $$ frameSct $$ aranges, us'') + return (infoSct $$ stringsSct $$ abbrevSct $$ lineSct $$ frameSct $$ aranges, us'') -- | Build an address range entry for one proc. -- With split sections, each proc needs its own entry, since they may get @@ -178,7 +182,7 @@ parent, B. procToDwarf :: DynFlags -> DebugBlock -> DwarfInfo procToDwarf df prc = DwarfSubprogram { dwChildren = map blockToDwarf (dblBlocks prc) - , dwName = case dblSourceTick prc of + , dwName = dwarfStringFromString $ case dblSourceTick prc of Just s at SourceNote{} -> sourceName s _otherwise -> showSDocDump df $ ppr $ dblLabel prc , dwLabel = dblCLabel prc ===================================== compiler/GHC/CmmToAsm/Dwarf/Types.hs ===================================== @@ -1,8 +1,14 @@ +{-# LANGUAGE RecordWildCards #-} + module GHC.CmmToAsm.Dwarf.Types ( -- * Dwarf information DwarfInfo(..) , pprDwarfInfo , pprAbbrevDecls + , dwarfInfoStrings + -- * Dwarf Strings section + , DwarfString + , dwarfStringsSection -- * Dwarf address range table , DwarfARange(..) , pprDwarfARanges @@ -48,18 +54,45 @@ import Data.Char import GHC.Platform.Regs +-- | A string in the DWARF @.debug_str@ section. +newtype DwarfString = DwarfString FastString + +dwarfStringFromString :: String -> DwarfString +dwarfStringFromString = dwarfStringFromFastString . fsLit + +dwarfStringFromFastString :: String -> DwarfString +dwarfStringFromFastString = DwarfString + +dwarfStringSymbol :: DwarfString -> SDoc +dwarfStringSymbol (DwarfString fs) = + text "_dbgfs_" <> getUnique fs + +debugStrSection :: SDoc +debugStrSection = text ".debug_str" + +pprDwarfString :: Platform -> DwarfString -> SDoc +pprDwarfString plat s = + sectionOffset plat (dwarfStringSymbol s) debugStrSection + +dwarfStringsSection :: [DwarfString] -> SDoc +dwarfStringsSection xs = text ".section" <+> debugStrSection $$ foldMap string xs + where + string :: DwarfString -> SDoc + string dstr@(DwarfString fstr) = + dwarfStringSymbol dstr <> colon $$ pprFastString fstr + -- | Individual dwarf records. Each one will be encoded as an entry in -- the @.debug_info@ section. data DwarfInfo = DwarfCompileUnit { dwChildren :: [DwarfInfo] - , dwName :: String - , dwProducer :: String - , dwCompDir :: String + , dwName :: DwarfString + , dwProducer :: DwarfString + , dwCompDir :: DwarfString , dwLowLabel :: CLabel , dwHighLabel :: CLabel , dwLineLabel :: PtrString } | DwarfSubprogram { dwChildren :: [DwarfInfo] - , dwName :: String + , dwName :: DwarfString , dwLabel :: CLabel , dwParent :: Maybe CLabel -- ^ label of DIE belonging to the parent tick @@ -68,9 +101,23 @@ data DwarfInfo , dwLabel :: CLabel , dwMarker :: Maybe CLabel } - | DwarfSrcNote { dwSrcSpan :: RealSrcSpan + | DwarfSrcNote { dwSpanFile :: !DwarfString + , dwSpanSLine :: !Int + , dwSpanSCol :: !Int + , dwSpanELine :: !Int + , dwSpanECol :: !Int } +-- | 'DwarfStrings' mentioned by the given 'DwarfInfo'. +dwarfInfoStrings :: DwarfInfo -> [DwarfString] +dwarfInfoStrings dwinfo = + case dwinfo of + DwarfCompileUnit {..} -> [dwName, dwProducer, dwCompDir] <> foldMap dwarfInfoStrings dwChildren + DwarfSubprogram {..} -> [dwName] <> foldMap dwarfInfoStrings dwChildren + DwarfBlock {..} -> foldMap dwarfInfoStrings dwChildren + DwarfSrcNote {..} -> [dwSpanFile] + + -- | Abbreviation codes used for encoding above records in the -- @.debug_info@ section. data DwarfAbbrev @@ -133,7 +180,7 @@ pprAbbrevDecls platform haveDebugLine = , (dW_AT_high_pc, dW_FORM_addr) ] $$ mkAbbrev DwAbbrGhcSrcNote dW_TAG_ghc_src_note dW_CHILDREN_no - [ (dW_AT_ghc_span_file, dW_FORM_string) + [ (dW_AT_ghc_span_file, dW_FORM_strp) , (dW_AT_ghc_span_start_line, dW_FORM_data4) , (dW_AT_ghc_span_start_col, dW_FORM_data2) , (dW_AT_ghc_span_end_line, dW_FORM_data4) @@ -163,10 +210,10 @@ pprDwarfInfoOpen :: Platform -> Bool -> DwarfInfo -> SDoc pprDwarfInfoOpen platform haveSrc (DwarfCompileUnit _ name producer compDir lowLabel highLabel lineLbl) = pprAbbrev DwAbbrCompileUnit - $$ pprString name - $$ pprString producer + $$ pprDwarfString name + $$ pprDwarfString producer $$ pprData4 dW_LANG_Haskell - $$ pprString compDir + $$ pprDwarfString compDir $$ pprWord platform (ppr lowLabel) $$ pprWord platform (ppr highLabel) $$ if haveSrc @@ -176,7 +223,7 @@ pprDwarfInfoOpen platform _ (DwarfSubprogram _ name label parent) = sdocWithDynFlags $ \df -> ppr (mkAsmTempDieLabel label) <> colon $$ pprAbbrev abbrev - $$ pprString name + $$ pprDwarfString name $$ pprString (renderWithStyle (initSDocContext df (mkCodeStyle CStyle)) (ppr label)) $$ pprFlag (externallyVisibleCLabel label) $$ pprWord platform (ppr label) @@ -201,7 +248,7 @@ pprDwarfInfoOpen platform _ (DwarfBlock _ label (Just marker)) = sdocWithDynFlag $$ pprWord platform (ppr $ mkAsmTempEndLabel marker) pprDwarfInfoOpen _ _ (DwarfSrcNote ss) = pprAbbrev DwAbbrGhcSrcNote - $$ pprString' (ftext $ srcSpanFile ss) + $$ pprDwarfString (ftext $ srcSpanFile ss) $$ pprData4 (fromIntegral $ srcSpanStartLine ss) $$ pprHalf (fromIntegral $ srcSpanStartCol ss) $$ pprData4 (fromIntegral $ srcSpanEndLine ss) @@ -573,13 +620,13 @@ pprLEBInt x | x >= -64 && x < 64 pprString' :: SDoc -> SDoc pprString' str = text "\t.asciz \"" <> str <> char '"' +-- | Generate a string constant. We take care to escape the string. +pprFastString :: FastString -> SDoc +pprFastString = pprString' . hcat . map escapeChar . unpackFS + -- | Generate a string constant. We take care to escape the string. pprString :: String -> SDoc -pprString str - = pprString' $ hcat $ map escapeChar $ - if str `lengthIs` utf8EncodedLength str - then str - else map (chr . fromIntegral) $ BS.unpack $ bytesFS $ mkFastString str +pprString = pprFastString . mkFastString -- | Escape a single non-unicode character escapeChar :: Char -> SDoc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/66e11eff47a3d298e75c17abda987e4ab4e09975 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/66e11eff47a3d298e75c17abda987e4ab4e09975 You're receiving 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 29 18:47:55 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 29 Apr 2020 14:47:55 -0400 Subject: [Git][ghc/ghc][wip/T17775] Wibbles Message-ID: <5ea9cbdb3d97a_6167c5ce1b0792053d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: d6553dc5 by Simon Peyton Jones at 2020-04-29T19:47:04+01:00 Wibbles Especially make major improvement to hsWrapDictBinders - - - - - 4 changed files: - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -365,7 +365,7 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty ; let doc = text "The first argument of ($) takes" orig1 = lexprCtOrigin arg1 ; (wrap_arg1, [arg2_sigma], op_res_ty) <- - matchActualFunTys doc orig1 (Just (unLoc arg1)) 1 arg1_ty + matchActualFunTysRho doc orig1 (Just (unLoc arg1)) 1 arg1_ty -- We have (arg1 $ arg2) -- So: arg1_ty = arg2_ty -> op_res_ty @@ -381,7 +381,7 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty (tcTypeKind arg2_sigma) liftedTypeKind -- Ignore the evidence. arg2_sigma must have type * or #, -- because we know (arg2_sigma -> op_res_ty) is well-kinded - -- (because otherwise matchActualFunTys would fail) + -- (because otherwise matchActualFunTysRho would fail) -- So this 'unifyKind' will either succeed with Refl, or will -- produce an insoluble constraint * ~ #, which we'll report later. @@ -415,7 +415,8 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty ; (op', op_ty) <- tcInferRhoNC op ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) - <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty + <- matchActualFunTysRho (mk_op_msg op) fn_orig + (Just (unLoc op)) 2 op_ty -- You might think we should use tcInferApp here, but there is -- too much impedance-matching, because tcApp may return wrappers as -- well as type-checked arguments. @@ -435,7 +436,8 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty tcExpr expr@(SectionR x op arg2) res_ty = do { (op', op_ty) <- tcInferRhoNC op ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) - <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) 2 op_ty + <- matchActualFunTysRho (mk_op_msg op) fn_orig + (Just (unLoc op)) 2 op_ty ; arg2' <- tcArg (unLoc op) arg2 arg2_ty 2 ; let expr' = SectionR x (mkLHsWrap wrap_fun op') arg2' act_res_ty = mkVisFunTy arg1_ty op_res_ty @@ -454,8 +456,8 @@ tcExpr expr@(SectionL x arg1 op) res_ty | otherwise = 2 ; (wrap_fn, (arg1_ty:arg_tys), op_res_ty) - <- matchActualFunTys (mk_op_msg op) fn_orig (Just (unLoc op)) - n_reqd_args op_ty + <- matchActualFunTysRho (mk_op_msg op) fn_orig + (Just (unLoc op)) n_reqd_args op_ty ; arg1' <- tcArg (unLoc op) arg1 arg1_ty 1 ; let expr' = SectionL x arg1' (mkLHsWrap wrap_fn op') act_res_ty = mkVisFunTys arg_tys op_res_ty @@ -1401,8 +1403,8 @@ tcArgs fun orig_fun_ty orig_args go n so_far fun_ty (HsEValArg loc arg : args) = do { (wrap, arg_ty, res_ty) - <- matchActualFunTy herald fun_orig (Just fun) - (n_val_args, so_far) fun_ty + <- matchActualFunTySigma herald fun_orig (Just fun) + (n_val_args, so_far) fun_ty ; arg' <- tcArg fun arg arg_ty n ; (args', inner_res_ty) <- go (n+1) (arg_ty:so_far) res_ty args ; return ( addArgWrap wrap $ HsEValArg loc arg' : args' @@ -1640,7 +1642,8 @@ tcSynArgA :: CtOrigin -- and a wrapper to be applied to the overall expression tcSynArgA orig sigma_ty arg_shapes res_shape thing_inside = do { (match_wrapper, arg_tys, res_ty) - <- matchActualFunTys herald orig Nothing (length arg_shapes) sigma_ty + <- matchActualFunTysRho herald orig Nothing + (length arg_shapes) sigma_ty -- match_wrapper :: sigma_ty "->" (arg_tys -> res_ty) ; ((result, res_wrapper), arg_wrappers) <- tc_syn_args_e arg_tys arg_shapes $ \ arg_results -> ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -413,7 +413,7 @@ tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside ; let expr_orig = lexprCtOrigin expr herald = text "A view pattern expression expects" ; (expr_wrap1, [inf_arg_ty], inf_res_ty) - <- matchActualFunTys herald expr_orig (Just (unLoc expr)) 1 expr_ty + <- matchActualFunTysRho herald expr_orig (Just (unLoc expr)) 1 expr_ty -- expr_wrap1 :: expr_ty "->" (inf_arg_ty -> inf_res_ty) -- Check that overall pattern is more polymorphic than arg type ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -383,11 +383,7 @@ hsWrapDictBinders wrap = go wrap emptyBag go (WpEvApp {}) acc = acc go (WpTyLam {}) acc = acc go (WpTyApp {}) acc = acc - go (WpLet binds) acc = go_binds binds `unionBags` acc - - go_binds (EvBinds bs) = mapBag eb_lhs bs - go_binds (TcEvBinds ebv) = pprPanic "hsWrapperDictBinds" (ppr ebv) - -- Should only be applied post zonking + go (WpLet _) acc = acc collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -31,7 +31,7 @@ module GHC.Tc.Utils.Unify ( matchExpectedTyConApp, matchExpectedAppTy, matchExpectedFunTys, - matchActualFunTys, matchActualFunTy, + matchActualFunTysRho, matchActualFunTySigma, matchExpectedFunKind, metaTyVarUpdateOK, occCheckForErrors, MetaTyVarUpdateResult(..) @@ -232,26 +232,27 @@ matchExpectedFunTys herald ctx arity orig_ty thing_inside -- Like 'matchExpectedFunTys', but used when you have an "actual" type, -- for example in function application --- This function instantiates at each polytype. -matchActualFunTys :: SDoc -- See Note [Herald for matchExpectedFunTys] - -> CtOrigin - -> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType - -> Arity - -> TcSigmaType - -> TcM (HsWrapper, [TcSigmaType], TcRhoType) --- If matchActualFunTys n ty = (wrap, [t1,..,tn], res_ty) +matchActualFunTysRho :: SDoc -- See Note [Herald for matchExpectedFunTys] + -> CtOrigin + -> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType + -> Arity + -> TcSigmaType + -> TcM (HsWrapper, [TcSigmaType], TcRhoType) +-- If matchActualFunTysRho n ty = (wrap, [t1,..,tn], res_ty) -- then wrap : ty ~> (t1 -> ... -> tn -> res_ty) -- and res_ty is a RhoType -matchActualFunTys herald ct_orig mb_thing n_val_args_wanted fun_ty +-- NB: the returned type is top-instantiated; it's a RhoType +matchActualFunTysRho herald ct_orig mb_thing n_val_args_wanted fun_ty = go n_val_args_wanted [] fun_ty where go 0 _ fun_ty = do { (wrap, rho) <- topInstantiate ct_orig fun_ty ; return (wrap, [], rho) } go n so_far fun_ty - = do { (wrap_fun1, arg_ty1, res_ty1) <- matchActualFunTy herald ct_orig mb_thing - (n_val_args_wanted, so_far) - fun_ty + = do { (wrap_fun1, arg_ty1, res_ty1) <- matchActualFunTySigma + herald ct_orig mb_thing + (n_val_args_wanted, so_far) + fun_ty ; (wrap_res, arg_tys, res_ty) <- go (n-1) (arg_ty1:so_far) res_ty1 ; let wrap_fun2 = mkWpFun idHsWrapper wrap_res arg_ty1 res_ty doc ; return (wrap_fun2 <.> wrap_fun1, arg_ty1:arg_tys, res_ty) } @@ -259,9 +260,9 @@ matchActualFunTys herald ct_orig mb_thing n_val_args_wanted fun_ty doc = text "When inferring the argument type of a function with type" <+> quotes (ppr fun_ty) --- | Variant of 'matchActualFunTys' that works when supplied only part --- (that is, to the right of some arrows) of the full function type -matchActualFunTy +-- | matchActualFunTySigm does looks for just one function arrow +-- returning an uninstantiated sigma-type +matchActualFunTySigma :: SDoc -- See Note [Herald for matchExpectedFunTys] -> CtOrigin -> Maybe (HsExpr GhcRn) -- The thing with type TcSigmaType @@ -269,13 +270,15 @@ matchActualFunTy -- types of values args to which function has -- been applied already (reversed) -- Both are used only for error messages) - -> TcSigmaType -- Type to analyse + -> TcSigmaType -- Type to analyse -> TcM (HsWrapper, TcSigmaType, TcSigmaType) -- See Note [matchActualFunTys error handling] for all these arguments --- If (wrap, arg_ty, res_ty) = matchActualFunTy ... fun_ty + +-- If (wrap, arg_ty, res_ty) = matchActualFunTySigma ... fun_ty -- then wrap :: fun_ty ~> (arg_ty -> res_ty) -- and NB: res_ty is an (uninstantiated) SigmaType -matchActualFunTy herald ct_orig mb_thing err_info fun_ty + +matchActualFunTySigma herald ct_orig mb_thing err_info fun_ty = go fun_ty -- Does not allocate unnecessary meta variables: if the input already is -- a function, we just take it apart. Not only is this efficient, @@ -291,19 +294,7 @@ matchActualFunTy herald ct_orig mb_thing err_info fun_ty -- in elsewhere). where - -- This function has a bizarre mechanic: it accumulates arguments on - -- the way down and also builds an argument list on the way up. Why: - -- 1. The returns args list and the accumulated args list might be different. - -- The accumulated args include all the arg types for the function, - -- including those from before this function was called. The returned - -- list should include only those arguments produced by this call of - -- matchActualFunTys - -- - -- 2. The HsWrapper can be built only on the way up. It seems (more) - -- bizarre to build the HsWrapper but not the arg_tys. - -- - -- Refactoring is welcome. - go :: TcSigmaType -- the remainder of the type as we're processing + go :: TcSigmaType -- The remainder of the type as we're processing -> TcM (HsWrapper, TcSigmaType, TcSigmaType) go ty | Just ty' <- tcView ty = go ty' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6553dc57a254eba88e7244ad1581957f616a9d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6553dc57a254eba88e7244ad1581957f616a9d2 You're receiving 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 29 19:35:10 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 29 Apr 2020 15:35:10 -0400 Subject: [Git][ghc/ghc][wip/T17917] 43 commits: Derive Ord instance for Extension Message-ID: <5ea9d6eec114d_61673f81cd4c695c793188e@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - de2f34e7 by Simon Peyton Jones at 2020-04-29T20:34:38+01:00 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. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! - - - - - 30 changed files: - 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/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Graph.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a6431f92a2a5fbaf58a647d4b332c5c7222309f6...de2f34e7f874a960a1c1059b47690651999fa58a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a6431f92a2a5fbaf58a647d4b332c5c7222309f6...de2f34e7f874a960a1c1059b47690651999fa58a You're receiving 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 29 20:14:02 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Wed, 29 Apr 2020 16:14:02 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] 55 commits: Change the fail operator argument of BindStmt to be a Maybe Message-ID: <5ea9e00a8c721_61673f819b417d1c793743@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - b15868a8 by Alan Zimmerman at 2020-04-29T21:13:18+01:00 Proof of Concept implementation of in-tree API Annotations This MR introduces a possible machinery to introduce API Annotations into the TTG extension points. It is intended to be a concrete example for discussion. It still needs to process comments. ---- Work in progress, adding more TTG extensions for annotations. And fixing ppr round-trip tests by being able to blank out in-tree annotations, as done with SrcSpans. This is needed for the case of class Foo a where for which current ppr does not print the "where". Rename AA to AddApiAnn and AA to AddAnn Add XConPatIn and XConPatOut Rebase ---- First pass at bringing in LocatedA for API anns in locations Treatment of ECP in parsing is provisional at this stage, leads to some horribly stuff in Parser.y and RdrHsSyn. It is an extensive but not invasive change. I think (AZ). Locally it reports some parsing tests using less memory. Add ApiAnns to the HsExpr data structure. rebase. Change HsMatchContext and HsStmtContext to use an id, not a GhcPass parameter. Add ApiAnns to Hs/Types Rebase Rebased 2020-03-25 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan ---- In-tree annotations: LHsDecl and LHsBind LocatedA ---- WIP on in-tree annotations ---- in-tree annotations: LHsType is now LocatedA ---- FunDeps is now also a HS data type ---- WIP. Added LocatedA to Pat, Expr, Decl And worked some more through Parser.y ---- LStmt now Located ---- Finished working through Parser.y, tests seem ok failures relate to annotations. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6c112c6b7bd35e622410b3e0035c886b5742c5df...b15868a8f81ad7578cbf3d784345cf603239a130 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6c112c6b7bd35e622410b3e0035c886b5742c5df...b15868a8f81ad7578cbf3d784345cf603239a130 You're receiving 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 29 20:21:14 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Wed, 29 Apr 2020 16:21:14 -0400 Subject: [Git][ghc/ghc][wip/hadrian-multi-comp] Hadrian: Improve tool-args command to support more components Message-ID: <5ea9e1bad9c51_6167120888bc793936e@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/hadrian-multi-comp at Glasgow Haskell Compiler / GHC Commits: 6519ef81 by Matthew Pickering at 2020-04-29T21:20:56+01:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 6 changed files: - hadrian/ghci-cabal - hadrian/ghci-stack - hadrian/hadrian.cabal - hadrian/hie-bios - hadrian/src/Rules.hs - + hadrian/src/Rules/ToolArgs.hs Changes: ===================================== hadrian/ghci-cabal ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" -ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool:ghc/Main.hs -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" +ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m ===================================== hadrian/ghci-stack ===================================== @@ -4,4 +4,4 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" -stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m ===================================== hadrian/hadrian.cabal ===================================== @@ -77,6 +77,7 @@ executable hadrian , Rules.Program , Rules.Register , Rules.Rts + , Rules.ToolArgs , Rules.Selftest , Rules.SimpleTargets , Rules.SourceDist ===================================== hadrian/hie-bios ===================================== @@ -3,7 +3,5 @@ # When run, this program will output a list of arguments which are necessary to # load the GHC library component into GHCi. The program is used by `ghcide` in # order to automatically set up the correct GHC API session for a project. -TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool-args -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT -echo -ighc >> $HIE_BIOS_OUTPUT -echo "ghc/Main.hs" >> $HIE_BIOS_OUTPUT +TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool:$1 -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT ===================================== hadrian/src/Rules.hs ===================================== @@ -24,43 +24,12 @@ import qualified Rules.Program import qualified Rules.Register import qualified Rules.Rts import qualified Rules.SimpleTargets +import Rules.ToolArgs import Settings import Settings.Program (programContext) import Target import UserSettings --- | @tool-args@ is used by tooling in order to get the arguments necessary --- to set up a GHC API session which can compile modules from GHC. When --- run, the target prints out the arguments that would be passed to @ghc@ --- during normal compilation to @stdout at . --- --- This target is called by the `ghci` script in order to load all of GHC's --- modules into GHCi. -toolArgsTarget :: Rules () -toolArgsTarget = do - "tool-args" ~> do - -- We can't build DLLs on Windows (yet). Actually we should only - -- include the dynamic way when we have a dynamic host GHC, but just - -- checking for Windows seems simpler for now. - let fake_target = target (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) - (Ghc ToolArgs Stage0) [] ["ignored"] - - -- need the autogenerated files so that they are precompiled - includesDependencies Stage0 >>= need - interpret fake_target Rules.Generate.compilerDependencies >>= need - - root <- buildRoot - let dir = buildDir (vanillaContext Stage0 compiler) - need [ root -/- dir -/- "Config.hs" ] - need [ root -/- dir -/- "GHC" -/- "Parser.hs" ] - need [ root -/- dir -/- "GHC" -/- "Parser" -/- "Lexer.hs" ] - need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Parser.hs" ] - need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Lexer.hs" ] - - -- Find out the arguments that are needed to load a module into the - -- session - arg_list <- interpret fake_target getArgs - liftIO $ putStrLn (intercalate "\n" arg_list) allStages :: [Stage] allStages = [minBound .. maxBound] ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -0,0 +1,128 @@ +module Rules.ToolArgs(toolArgsTarget) where + +import qualified Rules.Generate +import Development.Shake +import Target +import Context +import Stage +import Expression + +import Packages +import Settings +import Hadrian.Oracles.Cabal +import Hadrian.Haskell.Cabal.Type +import System.Directory (canonicalizePath) + +-- | @tool:@ is used by tooling in order to get the arguments necessary +-- to set up a GHC API session which can compile modules from GHC. When +-- run, the target prints out the arguments that would be passed to @ghc@ +-- during normal compilation to @stdout@ for the file passed as an +-- argument. +-- +-- This target is called by the `ghci.sh` script in order to load all of GHC's +-- modules into GHCi. It is invoked with argument `tool:ghc/Main.hs` in +-- that script so that we can load the whole library and executable +-- components into GHCi. +-- +-- In the future where we have multi-component ghci this code can be +-- modified to supply the right arguments for that. At the moment it is +-- also used for GHC's support for multi-component ghcide (see the +-- `hadrian/hie-bios` script). + + +-- | A phony target of form `tool:path/to/file.hs` which returns the +-- options needed to compile the specific file. +toolArgsTarget :: Rules () +toolArgsTarget = do + phonys (\s -> if "tool:" `isPrefixOf` s then Just (toolRuleBody (drop 5 s)) else Nothing) + +toolRuleBody :: FilePath -> Action () +toolRuleBody fp = do + mm <- dirMap + cfp <- liftIO $ canonicalizePath fp + case find (flip isPrefixOf cfp . fst) mm of + Just (_, (p, extra)) -> mkToolTarget extra p + Nothing -> fail $ "No prefixes matched " ++ show fp ++ " IN\n " ++ show mm + +mkToolTarget :: [String] -> Package -> Action () +mkToolTarget es p = do + -- This builds automatically generated dependencies. Not sure how to do + -- this generically yet. + allDeps + let fake_target = target (Context Stage0 p (if windowsHost then vanilla else dynamic)) + (Ghc ToolArgs Stage0) [] ["ignored"] + arg_list <- interpret fake_target getArgs + liftIO $ putStrLn (intercalate "\n" (arg_list ++ es)) +allDeps :: Action () +allDeps = do + do + -- We can't build DLLs on Windows (yet). Actually we should only + -- include the dynamic way when we have a dynamic host GHC, but just + -- checking for Windows seems simpler for now. + let fake_target = target (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) + (Ghc ToolArgs Stage0) [] ["ignored"] + + -- need the autogenerated files so that they are precompiled + includesDependencies Stage0 >>= need + interpret fake_target Rules.Generate.compilerDependencies >>= need + + root <- buildRoot + let dir = buildDir (vanillaContext Stage0 compiler) + need [ root -/- dir -/- "Config.hs" ] + need [ root -/- dir -/- "GHC" -/- "Parser.hs" ] + need [ root -/- dir -/- "GHC" -/- "Parser" -/- "Lexer.hs" ] + need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Parser.hs" ] + need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Lexer.hs" ] + +-- This list is quite a lot like stage0packages but doesn't include +-- critically the `exe:ghc` component as that depends on the GHC library +-- which takes a while to compile. +toolTargets :: [Package] +toolTargets = [ array + , bytestring + , templateHaskell + , containers + , deepseq + , directory + , exceptions + , filepath + , compiler + , ghcCompact + , ghcPrim + --, haskeline + , hp2ps + , hsc2hs + , pretty + , process + , rts + , stm + , time + , unlit + , xhtml ] + +-- | Create a mapping from files to which component it belongs to. +dirMap :: Action [(FilePath, (Package, [String]))] +dirMap = do + auto <- concatMapM go toolTargets + -- Mush the ghc executable into the compiler component so the whole of ghc is not built when + -- configuring + ghc_exe <- mkGhc + return (auto ++ [ghc_exe]) + + where + -- Make a separate target for the exe:ghc target because otherwise + -- configuring would build the whole GHC library which we probably + -- don't want to do. + mkGhc = do + let c = (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) + cd <- readContextData c + fp <- liftIO $ canonicalizePath "ghc/" + return (fp, (compiler, "-ighc" : modules cd ++ otherModules cd ++ ["ghc/Main.hs"])) + go p = do + let c = (Context Stage0 p (if windowsHost then vanilla else dynamic)) + -- readContextData has the effect of configuring the package so all + -- dependent packages will also be built. + cd <- readContextData c + ids <- liftIO $ mapM canonicalizePath [pkgPath p i | i <- srcDirs cd] + return $ map (,(p, modules cd ++ otherModules cd)) ids + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6519ef811c92219bc08508ab1fe858f748673eff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6519ef811c92219bc08508ab1fe858f748673eff You're receiving 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 29 20:22:13 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 29 Apr 2020 16:22:13 -0400 Subject: [Git][ghc/ghc][wip/T18049] PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info Message-ID: <5ea9e1f5c0f89_6167c5ce1b0794013c@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18049 at Glasgow Haskell Compiler / GHC Commits: 2874e1f7 by Sebastian Graf at 2020-04-29T22:22:01+02:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 6 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Tc/Types/Evidence.hs - + testsuite/tests/pmcheck/should_compile/T18049.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -33,7 +33,7 @@ import {-# SOURCE #-} GHC.HsToCore.Match ( matchWrapper ) import GHC.HsToCore.Monad import GHC.HsToCore.GuardedRHSs import GHC.HsToCore.Utils -import GHC.HsToCore.PmCheck ( needToRunPmCheck, addTyCsDs, checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Hs -- lots of things import GHC.Core -- lots of things @@ -145,12 +145,20 @@ dsHsBind dflags (VarBind { var_id = var else [] ; return (force_var, [core_bind]) } -dsHsBind dflags b@(FunBind { fun_id = L _ fun +dsHsBind dflags b@(FunBind { fun_id = L loc fun , fun_matches = matches , fun_ext = co_fn , fun_tick = tick }) - = do { (args, body) <- matchWrapper - (mkPrefixFunRhs (noLoc $ idName fun)) + = do { (args, body) <- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + -- FromSource might not be accurate (we don't have any + -- origin annotations for things in this module), but at + -- worst we do superfluous calls to the pattern match + -- oracle. + -- addTyCsDs: Add type evidence to the refinement type + -- predicate of the coverage checker + -- See Note [Type and Term Equality Propagation] in PmCheck + matchWrapper + (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body @@ -189,15 +197,7 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts , abs_exports = exports , abs_ev_binds = ev_binds , abs_binds = binds, abs_sig = has_sig }) - = do { ds_binds <- applyWhen (needToRunPmCheck dflags FromSource) - -- FromSource might not be accurate, but at worst - -- we do superfluous calls to the pattern match - -- oracle. - -- addTyCsDs: push type constraints deeper - -- for inner pattern match check - -- See Check, Note [Type and Term Equality Propagation] - (addTyCsDs (listToBag dicts)) - (dsLHsBinds binds) + = do { ds_binds <- addTyCsDs FromSource (listToBag dicts) (dsLHsBinds binds) ; ds_ev_binds <- dsTcEvBinds_s ev_binds @@ -206,7 +206,6 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind" - ----------------------- dsAbsBinds :: DynFlags -> [TyVar] -> [EvVar] -> [ABExport GhcTc] ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.HsToCore.ListComp import GHC.HsToCore.Utils import GHC.HsToCore.Arrows import GHC.HsToCore.Monad -import GHC.HsToCore.PmCheck ( checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Types.Name import GHC.Types.Name.Env import GHC.Core.FamInstEnv( topNormaliseType ) @@ -280,7 +280,8 @@ dsExpr hswrap@(XExpr (HsWrap co_fn e)) HsConLikeOut _ (RealDataCon dc) -> return $ varToCoreExpr (dataConWrapId dc) XExpr (HsWrap _ _) -> pprPanic "dsExpr: HsWrap inside HsWrap" (ppr hswrap) HsPar _ _ -> pprPanic "dsExpr: HsPar inside HsWrap" (ppr hswrap) - _ -> dsExpr e + _ -> addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + dsExpr e -- See Note [Detecting forced eta expansion] ; wrap' <- dsHsWrapper co_fn ; dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -14,7 +14,7 @@ Pattern Matching Coverage Checking. module GHC.HsToCore.PmCheck ( -- Checking and printing checkSingle, checkMatches, checkGuardMatches, - needToRunPmCheck, isMatchContextPmChecked, + isMatchContextPmChecked, -- See Note [Type and Term Equality Propagation] addTyCsDs, addScrutTmCs @@ -45,7 +45,7 @@ import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Types.Var (EvVar) import GHC.Core.Coercion -import GHC.Tc.Types.Evidence ( HsWrapper(..), isIdHsWrapper ) +import GHC.Tc.Types.Evidence (HsWrapper(..), isIdHsWrapper) import GHC.Tc.Utils.TcType (evVarPred) import {-# SOURCE #-} GHC.HsToCore.Expr (dsExpr, dsLExpr, dsSyntaxExpr) import {-# SOURCE #-} GHC.HsToCore.Binds (dsHsWrapper) @@ -53,6 +53,7 @@ import GHC.HsToCore.Utils (selectMatchVar) import GHC.HsToCore.Match.Literal (dsLit, dsOverLit) import GHC.HsToCore.Monad import GHC.Data.Bag +import GHC.Data.IOEnv (unsafeInterleaveM) import GHC.Data.OrdList import GHC.Core.TyCo.Rep import GHC.Core.Type @@ -1033,20 +1034,30 @@ Functions `addScrutTmCs' is responsible for generating these constraints. -} +-- | Locally update 'dsl_deltas' with the given action, but defer evaluation +-- with 'unsafeInterleaveM' in order not to do unnecessary work. locallyExtendPmDelta :: (Deltas -> DsM Deltas) -> DsM a -> DsM a -locallyExtendPmDelta ext k = getPmDeltas >>= ext >>= \deltas -> do - inh <- isInhabited deltas - -- If adding a constraint would lead to a contradiction, don't add it. - -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ - -- for why this is done. - if inh - then updPmDeltas deltas k - else k - --- | Add in-scope type constraints -addTyCsDs :: Bag EvVar -> DsM a -> DsM a -addTyCsDs ev_vars = - locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars)) +locallyExtendPmDelta ext k = do + deltas <- getPmDeltas + deltas' <- unsafeInterleaveM $ do + deltas' <- ext deltas + inh <- isInhabited deltas' + -- If adding a constraint would lead to a contradiction, don't add it. + -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ + -- for why this is done. + if inh + then pure deltas' + else pure deltas + updPmDeltas deltas' k + +-- | Add in-scope type constraints if the coverage checker might run and then +-- run the given action. +addTyCsDs :: Origin -> Bag EvVar -> DsM a -> DsM a +addTyCsDs origin ev_vars m = do + dflags <- getDynFlags + applyWhen (needToRunPmCheck dflags origin) + (locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars))) + m -- | Add equalities for the scrutinee to the local 'DsM' environment when -- checking a case expression: ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -10,7 +10,7 @@ module GHC.Tc.Types.Evidence ( (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, - pprHsWrapper, + pprHsWrapper, hsWrapDictBinders, -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), @@ -370,6 +370,21 @@ isErasableHsWrapper = go go WpTyApp{} = True go WpLet{} = False +hsWrapDictBinders :: HsWrapper -> Bag DictId +-- Collects the given dict Ids, bound by the wrapper, +-- that scope over the "hole" in the wrapper +hsWrapDictBinders wrap = go wrap + where + go WpHole = emptyBag + go (w1 `WpCompose` w2) = go w1 `unionBags` go w2 + go (WpFun _ w _ _) = go w + go (WpCast {}) = emptyBag + go (WpEvLam dict_id) = unitBag dict_id + go (WpEvApp {}) = emptyBag + go (WpTyLam {}) = emptyBag + go (WpTyApp {}) = emptyBag + go (WpLet {}) = emptyBag + collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, -- stopping as soon as you get to a non-lambda binder ===================================== testsuite/tests/pmcheck/should_compile/T18049.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +module Bug where + +import Data.Kind + +data SBool :: Bool -> Type where + SFalse :: SBool False + STrue :: SBool True + +f :: SBool b + -> (b ~ True => SBool b -> r) + -> (b ~ False => SBool b -> r) + -> r +f x t f = + case x of + SFalse -> f x + STrue -> t x + +g :: forall b. SBool b -> () +g x = f x + (\x' -> + case x' of + -- SFalse -> () + STrue -> ()) + (\_ -> ()) ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -118,6 +118,8 @@ test('T17977', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17977b', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T18049', normal, compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2874e1f73210303c745b6014600c975e6fba38f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2874e1f73210303c745b6014600c975e6fba38f7 You're receiving 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 30 01:07:39 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 29 Apr 2020 21:07:39 -0400 Subject: [Git][ghc/ghc][wip/T17775] Wibbles Message-ID: <5eaa24db1bfef_61673f81cd9bfa6c79664e9@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: a4249525 by Simon Peyton Jones at 2020-04-30T02:06:53+01:00 Wibbles esp to tcPolyCheck - - - - - 5 changed files: - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -697,7 +697,7 @@ tcPolyCheck prag_fn ; mono_name <- newNameAt (nameOccName name) nm_loc ; (wrap_gen, (wrap_res, matches')) <- setSrcSpan sig_loc $ -- Sets the binding location for the skolems - tcSkolemise ctxt (idType poly_id) $ \_ rho_ty -> + tcSkolemiseScoped ctxt (idType poly_id) $ \rho_ty -> -- Unwraps multiple layers; e.g -- f :: forall a. Eq a => forall b. Ord b => blah -- NB: tcSkolemise makes fresh type variables ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -1574,7 +1574,7 @@ tcSynArgE :: CtOrigin -- ^ returns a wrapper :: (type of right shape) "->" (type passed in) tcSynArgE orig sigma_ty syn_ty thing_inside = do { (skol_wrap, (result, ty_wrapper)) - <- tcSkolemise GenSigCtxt sigma_ty $ \ _ rho_ty -> + <- tcSkolemise GenSigCtxt sigma_ty $ \ rho_ty -> go rho_ty syn_ty ; return (result, skol_wrap <.> ty_wrapper) } where @@ -1726,22 +1726,10 @@ in the other order, the extra signature in f2 is reqd. tcExprSig :: LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcType) tcExprSig expr (CompleteSig { sig_bndr = poly_id, sig_loc = loc }) = setSrcSpan loc $ -- Sets the location for the implication constraint - do { (tv_prs, theta, tau) <- tcInstType tcInstSkolTyVars poly_id - ; given <- newEvVars theta - ; traceTc "tcExprSig: CompleteSig" $ - vcat [ text "poly_id:" <+> ppr poly_id <+> dcolon <+> ppr (idType poly_id) - , text "tv_prs:" <+> ppr tv_prs ] - - ; let skol_info = SigSkol ExprSigCtxt (idType poly_id) tv_prs - skol_tvs = map snd tv_prs - ; (ev_binds, expr') <- checkConstraints skol_info skol_tvs given $ - tcExtendNameTyVarEnv tv_prs $ - tcCheckPolyExprNC expr tau - - ; let poly_wrap = mkWpTyLams skol_tvs - <.> mkWpLams given - <.> mkWpLet ev_binds - ; return (mkLHsWrap poly_wrap expr', idType poly_id) } + do { let poly_ty = idType poly_id + ; (wrap, expr') <- tcSkolemiseScoped ExprSigCtxt poly_ty $ \rho_ty -> + tcCheckMonoExprNC expr rho_ty + ; return (mkLHsWrap wrap expr', poly_ty) } tcExprSig expr sig@(PartialSig { psig_name = name, sig_loc = loc }) = setSrcSpan loc $ -- Sets the location for the implication constraint ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -777,7 +777,7 @@ tcSpecWrapper :: UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper -- See Note [Handling SPECIALISE pragmas], wrinkle 1 tcSpecWrapper ctxt poly_ty spec_ty = do { (sk_wrap, inst_wrap) - <- tcSkolemise ctxt spec_ty $ \ _ spec_tau -> + <- tcSkolemise ctxt spec_ty $ \ spec_tau -> do { (inst_wrap, tau) <- topInstantiate orig poly_ty ; _ <- unifyType Nothing spec_tau tau -- Deliberately ignore the evidence ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1993,9 +1993,9 @@ isSigmaTy _ = False isRhoTy :: TcType -> Bool -- True of TcRhoTypes; see Note [TcRhoType] isRhoTy ty | Just ty' <- tcView ty = isRhoTy ty' -isRhoTy (ForAllTy {}) = False -isRhoTy (FunTy { ft_af = VisArg, ft_res = r }) = isRhoTy r -isRhoTy _ = True +isRhoTy (ForAllTy {}) = False +isRhoTy (FunTy { ft_af = InvisArg }) = False +isRhoTy _ = True -- | Like 'isRhoTy', but also says 'True' for 'Infer' types isRhoExpTy :: ExpType -> Bool ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -14,7 +14,7 @@ module GHC.Tc.Utils.Unify ( -- Full-blown subsumption tcWrapResult, tcWrapResultO, tcWrapResultMono, - tcSkolemise, tcSkolemiseET, + tcSkolemise, tcSkolemiseScoped, tcSkolemiseET, tcSubType, tcSubTypeSigma, tcSubTypePat, checkConstraints, checkTvConstraints, buildImplicationFor, buildTvImplication, emitResidualTvConstraint, @@ -160,7 +160,7 @@ matchExpectedFunTys herald ctx arity orig_ty thing_inside go acc_arg_tys n ty | (tvs, theta, _) <- tcSplitSigmaTy ty , not (null tvs && null theta) - = do { (wrap_gen, (wrap_res, result)) <- tcSkolemise ctx ty $ \_ ty' -> + = do { (wrap_gen, (wrap_res, result)) <- tcSkolemise ctx ty $ \ty' -> go acc_arg_tys n ty' ; return (wrap_gen <.> wrap_res, result) } @@ -611,7 +611,7 @@ tc_sub_type unify inst_orig ctxt ty_actual ty_expected , text "ty_expected =" <+> ppr ty_expected ] ; (sk_wrap, inner_wrap) - <- tcSkolemise ctxt ty_expected $ \ _ sk_rho -> + <- tcSkolemise ctxt ty_expected $ \ sk_rho -> do { (wrap, rho_a) <- topInstantiate inst_orig ty_actual ; cow <- unify rho_a sk_rho ; return (mkWpCastN cow <.> wrap) } @@ -937,49 +937,53 @@ the thinking. * * ********************************************************************* -} --- | Take an "expected type" and strip off quantifiers to expose the --- type underneath, binding the new skolems for the @thing_inside at . --- The returned 'HsWrapper' has type @specific_ty -> expected_ty at . -tcSkolemise :: UserTypeCtxt -> TcSigmaType - -> ([TcTyVar] -> TcType -> TcM result) - -- ^ These are only ever used for scoped type variables. - -> TcM (HsWrapper, result) - -- ^ The expression has type: spec_ty -> expected_ty +{- Note [Skolemisation] +~~~~~~~~~~~~~~~~~~~~~~~ +tcSkolemise takes "expected type" and strip off quantifiers to expose the +type underneath, binding the new skolems for the 'thing_inside' +The returned 'HsWrapper' has type (specific_ty -> expected_ty). + +Note: + +* tcSkolemiseScoped deals specially with just the outer forall, + because only the outer forall has type variables that scope + over the body + +-} + +tcSkolemise, tcSkolemiseScoped + :: UserTypeCtxt -> TcSigmaType + -> (TcType -> TcM result) + -> TcM (HsWrapper, result) + -- ^ The wrapper has type: spec_ty ~> expected_ty + +tcSkolemiseScoped ctxt expected_ty thing_inside + = do { (wrap, tv_prs, given, rho_ty) <- topSkolemise expected_ty + ; let skol_tvs = map snd tv_prs + skol_info = SigSkol ctxt expected_ty tv_prs + + ; (ev_binds, res) + <- checkConstraints skol_info skol_tvs given $ + tcExtendNameTyVarEnv tv_prs $ + thing_inside rho_ty + + ; return (wrap <.> mkWpLet ev_binds, res) } tcSkolemise ctxt expected_ty thing_inside -- We expect expected_ty to be a forall-type -- If not, the call is a no-op - = do { traceTc "tcSkolemise" Outputable.empty - ; (wrap, tv_prs, given, rho') <- topSkolemise expected_ty - - ; lvl <- getTcLevel - ; when debugIsOn $ - traceTc "tcSkolemise" $ vcat [ - ppr lvl, - text "expected_ty" <+> ppr expected_ty, - text "inst tyvars" <+> ppr tv_prs, - text "given" <+> ppr given, - text "inst type" <+> ppr rho' ] - - -- Generally we must check that the "forall_tvs" haven't been constrained - -- The interesting bit here is that we must include the free variables - -- of the expected_ty. Here's an example: - -- runST (newVar True) - -- Here, if we don't make a check, we'll get a type (ST s (MutVar s Bool)) - -- for (newVar True), with s fresh. Then we unify with the runST's arg type - -- forall s'. ST s' a. That unifies s' with s, and a with MutVar s Bool. - -- So now s' isn't unconstrained because it's linked to a. - -- - -- However [Oct 10] now that the untouchables are a range of - -- TcTyVars, all this is handled automatically with no need for - -- extra faffing around + | isRhoTy expected_ty + = do { res <- thing_inside expected_ty + ; return (idHsWrapper, res) } + | otherwise + = do { (wrap, tv_prs, given, rho_ty) <- topSkolemise expected_ty - ; let tvs' = map snd tv_prs + ; let skol_tvs = map snd tv_prs skol_info = SigSkol ctxt expected_ty tv_prs - ; (ev_binds, result) <- checkConstraints skol_info tvs' given $ - tcExtendNameTyVarEnv tv_prs $ - thing_inside tvs' rho' + ; (ev_binds, result) + <- checkConstraints skol_info skol_tvs given $ + thing_inside rho_ty ; return (wrap <.> mkWpLet ev_binds, result) } -- The ev_binds returned by checkConstraints is very @@ -992,7 +996,8 @@ tcSkolemiseET :: UserTypeCtxt -> ExpSigmaType tcSkolemiseET _ et@(Infer {}) thing_inside = (idHsWrapper, ) <$> thing_inside et tcSkolemiseET ctxt (Check ty) thing_inside - = tcSkolemise ctxt ty $ \_ -> thing_inside . mkCheckExpType + = tcSkolemise ctxt ty $ \rho_ty -> + thing_inside (mkCheckExpType rho_ty) checkConstraints :: SkolemInfo -> [TcTyVar] -- Skolems View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a4249525036262c9ecf52cbcdd9ad70304c53d57 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a4249525036262c9ecf52cbcdd9ad70304c53d57 You're receiving 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 30 05:57:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 01:57:05 -0400 Subject: [Git][ghc/ghc][master] 7 commits: Document backpack fields in DynFlags Message-ID: <5eaa68b12b450_61673f81cc913ba07985794@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToByteCode.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9...8bfb0219587b969d5c8f723c46d433e9493958b4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9...8bfb0219587b969d5c8f723c46d433e9493958b4 You're receiving 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 30 05:57:49 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 01:57:49 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Allow block arguments in arrow control operators Message-ID: <5eaa68ddd9cbc_616787c09cc79905e2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 21 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Utils/Zonk.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/lambda_case.rst - + testsuite/tests/arrows/should_run/ArrowLambdaCase.hs - + testsuite/tests/arrows/should_run/ArrowLambdaCase.stdout - testsuite/tests/arrows/should_run/all.T - + testsuite/tests/parser/should_compile/BlockArgumentsArrowCmds.hs - + testsuite/tests/parser/should_compile/ParserArrowLambdaCase.hs - testsuite/tests/parser/should_compile/all.T - + testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.hs - + testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.stderr - testsuite/tests/parser/should_fail/all.T Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -1330,6 +1330,14 @@ data HsCmd id -- For details on above see note [Api annotations] in GHC.Parser.Annotation + | HsCmdLamCase (XCmdLamCase id) + (MatchGroup id (LHsCmd id)) -- bodies are HsCmd's + -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnLam', + -- 'ApiAnnotation.AnnCase','ApiAnnotation.AnnOpen' @'{'@, + -- 'ApiAnnotation.AnnClose' @'}'@ + + -- For details on above see note [Api annotations] in GHC.Parser.Annotation + | HsCmdIf (XCmdIf id) (SyntaxExpr id) -- cond function (LHsExpr id) -- predicate @@ -1371,6 +1379,7 @@ type instance XCmdApp (GhcPass _) = NoExtField type instance XCmdLam (GhcPass _) = NoExtField type instance XCmdPar (GhcPass _) = NoExtField type instance XCmdCase (GhcPass _) = NoExtField +type instance XCmdLamCase (GhcPass _) = NoExtField type instance XCmdIf (GhcPass _) = NoExtField type instance XCmdLet (GhcPass _) = NoExtField @@ -1460,6 +1469,9 @@ ppr_cmd (HsCmdCase _ expr matches) = sep [ sep [text "case", nest 4 (ppr expr), ptext (sLit "of")], nest 2 (pprMatches matches) ] +ppr_cmd (HsCmdLamCase _ matches) + = sep [ text "\\case", nest 2 (pprMatches matches) ] + ppr_cmd (HsCmdIf _ _ e ct ce) = sep [hsep [text "if", nest 2 (ppr e), ptext (sLit "then")], nest 4 (ppr ct), ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -599,6 +599,7 @@ type family XCmdApp x type family XCmdLam x type family XCmdPar x type family XCmdCase x +type family XCmdLamCase x type family XCmdIf x type family XCmdLet x type family XCmdDo x ===================================== compiler/GHC/HsToCore/Arrows.hs ===================================== @@ -447,45 +447,12 @@ dsCmd ids local_vars stack_ty res_ty (HsCmdApp _ cmd arg) env_ids = do free_vars `unionDVarSet` (exprFreeIdsDSet core_arg `uniqDSetIntersectUniqSet` local_vars)) --- D; ys |-a cmd : stk t' --- ----------------------------------------------- --- D; xs |-a \ p1 ... pk -> cmd : (t1,...(tk,stk)...) t' --- --- ---> premap (\ ((xs), (p1, ... (pk,stk)...)) -> ((ys),stk)) cmd - dsCmd ids local_vars stack_ty res_ty (HsCmdLam _ (MG { mg_alts = (L _ [L _ (Match { m_pats = pats , m_grhss = GRHSs _ [L _ (GRHS _ [] body)] _ })]) })) - env_ids = do - let pat_vars = mkVarSet (collectPatsBinders pats) - let - local_vars' = pat_vars `unionVarSet` local_vars - (pat_tys, stack_ty') = splitTypeAt (length pats) stack_ty - (core_body, free_vars, env_ids') - <- dsfixCmd ids local_vars' stack_ty' res_ty body - param_ids <- mapM newSysLocalDsNoLP pat_tys - stack_id' <- newSysLocalDs stack_ty' - - -- the expression is built from the inside out, so the actions - -- are presented in reverse order - - let - -- build a new environment, plus what's left of the stack - core_expr = buildEnvStack env_ids' stack_id' - in_ty = envStackType env_ids stack_ty - in_ty' = envStackType env_ids' stack_ty' - - fail_expr <- mkFailExpr LambdaExpr in_ty' - -- match the patterns against the parameters - match_code <- matchSimplys (map Var param_ids) LambdaExpr pats core_expr - fail_expr - -- match the parameters against the top of the old stack - (stack_id, param_code) <- matchVarStack param_ids stack_id' match_code - -- match the old environment and stack against the input - select_code <- matchEnvStack env_ids stack_id param_code - return (do_premap ids in_ty in_ty' res_ty select_code core_body, - free_vars `uniqDSetMinusUniqSet` pat_vars) + env_ids + = dsCmdLam ids local_vars stack_ty res_ty pats body env_ids dsCmd ids local_vars stack_ty res_ty (HsCmdPar _ cmd) env_ids = dsLCmd ids local_vars stack_ty res_ty cmd env_ids @@ -626,6 +593,12 @@ dsCmd ids local_vars stack_ty res_ty return (do_premap ids in_ty sum_ty res_ty core_matches core_choices, exprFreeIdsDSet core_body `uniqDSetIntersectUniqSet` local_vars) +dsCmd ids local_vars stack_ty res_ty + (HsCmdLamCase _ mg at MG { mg_ext = MatchGroupTc [arg_ty] _ }) env_ids = do + arg_id <- newSysLocalDs arg_ty + let case_cmd = noLoc $ HsCmdCase noExtField (nlHsVar arg_id) mg + dsCmdLam ids local_vars stack_ty res_ty [nlVarPat arg_id] case_cmd env_ids + -- D; ys |-a cmd : stk --> t -- ---------------------------------- -- D; xs |-a let binds in cmd : stk --> t @@ -693,7 +666,7 @@ dsCmd ids local_vars stack_ty res_ty (XCmd (HsWrap wrap cmd)) env_ids = do core_wrap <- dsHsWrapper wrap return (core_wrap core_cmd, env_ids') -dsCmd _ _ _ _ _ c = pprPanic "dsCmd" (ppr c) +dsCmd _ _ _ _ c _ = pprPanic "dsCmd" (ppr c) -- D; ys |-a c : stk --> t (ys <= xs) -- --------------------- @@ -753,6 +726,52 @@ trimInput build_arrow (core_cmd, free_vars) <- build_arrow env_ids return (core_cmd, free_vars, dVarSetElems free_vars)) +-- Desugaring for both HsCmdLam and HsCmdLamCase. +-- +-- D; ys |-a cmd : stk t' +-- ----------------------------------------------- +-- D; xs |-a \ p1 ... pk -> cmd : (t1,...(tk,stk)...) t' +-- +-- ---> premap (\ ((xs), (p1, ... (pk,stk)...)) -> ((ys),stk)) cmd +dsCmdLam :: DsCmdEnv -- arrow combinators + -> IdSet -- set of local vars available to this command + -> Type -- type of the stack (right-nested tuple) + -> Type -- return type of the command + -> [LPat GhcTc] -- argument patterns to desugar + -> LHsCmd GhcTc -- body to desugar + -> [Id] -- list of vars in the input to this command + -- This is typically fed back, + -- so don't pull on it too early + -> DsM (CoreExpr, -- desugared expression + DIdSet) -- subset of local vars that occur free +dsCmdLam ids local_vars stack_ty res_ty pats body env_ids = do + let pat_vars = mkVarSet (collectPatsBinders pats) + let local_vars' = pat_vars `unionVarSet` local_vars + (pat_tys, stack_ty') = splitTypeAt (length pats) stack_ty + (core_body, free_vars, env_ids') + <- dsfixCmd ids local_vars' stack_ty' res_ty body + param_ids <- mapM newSysLocalDsNoLP pat_tys + stack_id' <- newSysLocalDs stack_ty' + + -- the expression is built from the inside out, so the actions + -- are presented in reverse order + + let -- build a new environment, plus what's left of the stack + core_expr = buildEnvStack env_ids' stack_id' + in_ty = envStackType env_ids stack_ty + in_ty' = envStackType env_ids' stack_ty' + + fail_expr <- mkFailExpr LambdaExpr in_ty' + -- match the patterns against the parameters + match_code <- matchSimplys (map Var param_ids) LambdaExpr pats core_expr + fail_expr + -- match the parameters against the top of the old stack + (stack_id, param_code) <- matchVarStack param_ids stack_id' match_code + -- match the old environment and stack against the input + select_code <- matchEnvStack env_ids stack_id param_code + return (do_premap ids in_ty in_ty' res_ty select_code core_body, + free_vars `uniqDSetMinusUniqSet` pat_vars) + {- Translation of command judgements of the form ===================================== compiler/GHC/HsToCore/Coverage.hs ===================================== @@ -861,6 +861,8 @@ addTickHsCmd (HsCmdCase x e mgs) = liftM2 (HsCmdCase x) (addTickLHsExpr e) (addTickCmdMatchGroup mgs) +addTickHsCmd (HsCmdLamCase x mgs) = + liftM (HsCmdLamCase x) (addTickCmdMatchGroup mgs) addTickHsCmd (HsCmdIf x cnd e1 c2 c3) = liftM3 (HsCmdIf x cnd) (addBinTickLHsExpr (BinBox CondBinBox) e1) ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1240,6 +1240,9 @@ instance ( a ~ GhcPass p [ toHie expr , toHie alts ] + HsCmdLamCase _ alts -> + [ toHie alts + ] HsCmdIf _ _ a b c -> [ toHie a , toHie b ===================================== compiler/GHC/Parser.y ===================================== @@ -2765,11 +2765,10 @@ aexp :: { ECP } (mj AnnLet $1:mj AnnIn $3 :(fst $ unLoc $2)) } | '\\' 'lcase' altslist - {% runPV $3 >>= \ $3 -> - fmap ecpFromExp $ - ams (sLL $1 $> $ HsLamCase noExtField + { ECP $ $3 >>= \ $3 -> + amms (mkHsLamCasePV (comb2 $1 $>) (mkMatchGroup FromSource (snd $ unLoc $3))) - (mj AnnLam $1:mj AnnCase $2:(fst $ unLoc $3)) } + (mj AnnLam $1:mj AnnCase $2:(fst $ unLoc $3)) } | 'if' exp optSemi 'then' exp optSemi 'else' exp {% runECP_P $2 >>= \ $2 -> return $ ECP $ @@ -2886,11 +2885,11 @@ aexp2 :: { ECP } | quasiquote { ECP $ mkHsSplicePV $1 } -- arrow notation extension - | '(|' aexp2 cmdargs '|)' {% runECP_P $2 >>= \ $2 -> - fmap ecpFromCmd $ - ams (sLL $1 $> $ HsCmdArrForm noExtField $2 Prefix - Nothing (reverse $3)) - [mu AnnOpenB $1,mu AnnCloseB $4] } + | '(|' aexp cmdargs '|)' {% runECP_P $2 >>= \ $2 -> + fmap ecpFromCmd $ + ams (sLL $1 $> $ HsCmdArrForm noExtField $2 Prefix + Nothing (reverse $3)) + [mu AnnOpenB $1,mu AnnCloseB $4] } splice_exp :: { LHsExpr GhcPs } : splice_untyped { mapLoc (HsSpliceE noExtField) $1 } @@ -2914,8 +2913,9 @@ cmdargs :: { [LHsCmdTop GhcPs] } | {- empty -} { [] } acmd :: { LHsCmdTop GhcPs } - : aexp2 {% runECP_P $1 >>= \ cmd -> - return (sL1 cmd $ HsCmdTop noExtField cmd) } + : aexp {% runECP_P $1 >>= \ cmd -> + runPV (checkCmdBlockArguments cmd) >>= \ _ -> + return (sL1 cmd $ HsCmdTop noExtField cmd) } cvtopbody :: { ([AddAnn],[LHsDecl GhcPs]) } : '{' cvtopdecls0 '}' { ([mj AnnOpenC $1 ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -53,7 +53,7 @@ module GHC.Parser.PostProcess ( -- Bunch of functions in the parser monad for -- checking and constructing values checkImportDecl, - checkExpBlockArguments, + checkExpBlockArguments, checkCmdBlockArguments, checkPrecP, -- Int -> P Int checkContext, -- HsType -> P HsContext checkPattern, -- HsExp -> P HsPat @@ -1760,6 +1760,8 @@ class b ~ (Body b) GhcPs => DisambECP b where mkHsOpAppPV :: SrcSpan -> Located b -> Located (InfixOp b) -> Located b -> PV (Located b) -- | Disambiguate "case ... of ..." mkHsCasePV :: SrcSpan -> LHsExpr GhcPs -> MatchGroup GhcPs (Located b) -> PV (Located b) + -- | Disambiguate @\\case ...@ (lambda case) + mkHsLamCasePV :: SrcSpan -> MatchGroup GhcPs (Located b) -> PV (Located b) -- | Function argument representation type FunArg b -- | Bring superclass constraints on FunArg into scope. @@ -1874,6 +1876,7 @@ instance DisambECP (HsCmd GhcPs) where let cmdArg c = L (getLoc c) $ HsCmdTop noExtField c return $ L l $ HsCmdArrForm noExtField op Infix Nothing [cmdArg c1, cmdArg c2] mkHsCasePV l c mg = return $ L l (HsCmdCase noExtField c mg) + mkHsLamCasePV l mg = return $ L l (HsCmdLamCase noExtField mg) type FunArg (HsCmd GhcPs) = HsExpr GhcPs superFunArg m = m mkHsAppPV l c e = do @@ -1930,6 +1933,7 @@ instance DisambECP (HsExpr GhcPs) where mkHsOpAppPV l e1 op e2 = do return $ L l $ OpApp noExtField e1 op e2 mkHsCasePV l e mg = return $ L l (HsCase noExtField e mg) + mkHsLamCasePV l mg = return $ L l (HsLamCase noExtField mg) type FunArg (HsExpr GhcPs) = HsExpr GhcPs superFunArg m = m mkHsAppPV l e1 e2 = do @@ -2014,6 +2018,7 @@ instance DisambECP (PatBuilder GhcPs) where superInfixOp m = m mkHsOpAppPV l p1 op p2 = return $ L l $ PatBuilderOpApp p1 op p2 mkHsCasePV l _ _ = addFatalError l $ text "(case ... of ...)-syntax in pattern" + mkHsLamCasePV l _ = addFatalError l $ text "(\\case ...)-syntax in pattern" type FunArg (PatBuilder GhcPs) = PatBuilder GhcPs superFunArg m = m mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2) ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -495,6 +495,10 @@ rnCmd (HsCmdCase x expr matches) ; (new_matches, ms_fvs) <- rnMatchGroup CaseAlt rnLCmd matches ; return (HsCmdCase x new_expr new_matches, e_fvs `plusFV` ms_fvs) } +rnCmd (HsCmdLamCase x matches) + = do { (new_matches, ms_fvs) <- rnMatchGroup CaseAlt rnLCmd matches + ; return (HsCmdLamCase x new_matches, ms_fvs) } + rnCmd (HsCmdIf x _ p b1 b2) = do { (p', fvP) <- rnLExpr p ; (b1', fvB1) <- rnLCmd b1 @@ -540,6 +544,8 @@ methodNamesCmd (HsCmdLam _ match) = methodNamesMatch match methodNamesCmd (HsCmdCase _ _ matches) = methodNamesMatch matches `addOneFV` choiceAName +methodNamesCmd (HsCmdLamCase _ matches) + = methodNamesMatch matches `addOneFV` choiceAName --methodNamesCmd _ = emptyFVs -- Other forms can't occur in commands, but it's not convenient ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -151,13 +151,14 @@ tc_cmd env (HsCmdLet x (L l binds) (L body_loc body)) res_ty tc_cmd env in_cmd@(HsCmdCase x scrut matches) (stk, res_ty) = addErrCtxt (cmdCtxt in_cmd) $ do (scrut', scrut_ty) <- tcInferRho scrut - matches' <- tcMatchesCase match_ctxt scrut_ty matches (mkCheckExpType res_ty) + matches' <- tcCmdMatches env scrut_ty matches (stk, res_ty) return (HsCmdCase x scrut' matches') - where - match_ctxt = MC { mc_what = CaseAlt, - mc_body = mc_body } - mc_body body res_ty' = do { res_ty' <- expTypeToType res_ty' - ; tcCmd env body (stk, res_ty') } + +tc_cmd env in_cmd@(HsCmdLamCase x matches) (stk, res_ty) + = addErrCtxt (cmdCtxt in_cmd) $ do + (co, [scrut_ty], stk') <- matchExpectedCmdArgs 1 stk + matches' <- tcCmdMatches env scrut_ty matches (stk', res_ty) + return (mkHsCmdWrap (mkWpCastN co) (HsCmdLamCase x matches')) tc_cmd env (HsCmdIf x NoSyntaxExprRn pred b1 b2) res_ty -- Ordinary 'if' = do { pred' <- tcLExpr pred (mkCheckExpType boolTy) @@ -330,6 +331,20 @@ tc_cmd _ cmd _ = failWithTc (vcat [text "The expression", nest 2 (ppr cmd), text "was found where an arrow command was expected"]) +-- | Typechecking for case command alternatives. Used for both +-- 'HsCmdCase' and 'HsCmdLamCase'. +tcCmdMatches :: CmdEnv + -> TcType -- ^ type of the scrutinee + -> MatchGroup GhcRn (LHsCmd GhcRn) -- ^ case alternatives + -> CmdType + -> TcM (MatchGroup GhcTcId (LHsCmd GhcTcId)) +tcCmdMatches env scrut_ty matches (stk, res_ty) + = tcMatchesCase match_ctxt scrut_ty matches (mkCheckExpType res_ty) + where + match_ctxt = MC { mc_what = CaseAlt, + mc_body = mc_body } + mc_body body res_ty' = do { res_ty' <- expTypeToType res_ty' + ; tcCmd env body (stk, res_ty') } matchExpectedCmdArgs :: Arity -> TcType -> TcM (TcCoercionN, [TcType], TcType) matchExpectedCmdArgs 0 ty ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -995,6 +995,10 @@ zonkCmd env (HsCmdCase x expr ms) new_ms <- zonkMatchGroup env zonkLCmd ms return (HsCmdCase x new_expr new_ms) +zonkCmd env (HsCmdLamCase x ms) + = do new_ms <- zonkMatchGroup env zonkLCmd ms + return (HsCmdLamCase x new_ms) + zonkCmd env (HsCmdIf x eCond ePred cThen cElse) = do { (env1, new_eCond) <- zonkSyntaxExpr env eCond ; new_ePred <- zonkLExpr env1 ePred ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -104,6 +104,21 @@ Template Haskell - The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested splices do not lead directly to compile-time evaluation. (!2288) +Arrow notation +~~~~~~~~~~~~~~ + + - When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension + now additionally allows ``\case`` syntax to be used as a command in ``proc`` + notation. + + - When combined with :extension:`Arrows`, the effects of the + :extension:`BlockArguments` extension now also apply to applications of + arrow control operators in ``(|`` banana brackets ``|)``: :: + + (| untilA (increment -< x + y) do + within 0.5 -< x + ... |) + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ @@ -182,4 +197,3 @@ for further change information. 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/exts/lambda_case.rst ===================================== @@ -25,4 +25,11 @@ Note that ``\case`` starts a layout, so you can write :: ... pN -> eN +Additionally, since GHC 8.12.1, combining :extension:`LambdaCase` with +:extension:`Arrows` allows ``\case`` syntax to be used as a command in +``proc`` notation: :: + proc x -> (f -< x) `catchA` \case + p1 -> cmd1 + ... + pN -> cmdN ===================================== testsuite/tests/arrows/should_run/ArrowLambdaCase.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE Arrows, LambdaCase #-} +module Main (main) where + +import Control.Arrow + +main :: IO () +main = do + putStrLn $ foo (Just 42) + putStrLn $ foo (Just 500) + putStrLn $ foo Nothing + +foo :: ArrowChoice p => p (Maybe Int) String +foo = proc x -> + (| id (\case + Just x | x > 100 -> returnA -< "big " ++ show x + | otherwise -> returnA -< "small " ++ show x + Nothing -> returnA -< "none") + |) x ===================================== testsuite/tests/arrows/should_run/ArrowLambdaCase.stdout ===================================== @@ -0,0 +1,3 @@ +small 42 +big 500 +none ===================================== testsuite/tests/arrows/should_run/all.T ===================================== @@ -3,4 +3,4 @@ test('arrowrun002', when(fast(), skip), compile_and_run, ['']) test('arrowrun003', normal, compile_and_run, ['']) test('arrowrun004', when(fast(), skip), compile_and_run, ['']) test('T3822', normal, compile_and_run, ['']) - +test('ArrowLambdaCase', normal, compile_and_run, ['']) ===================================== testsuite/tests/parser/should_compile/BlockArgumentsArrowCmds.hs ===================================== @@ -0,0 +1,22 @@ +{-# LANGUAGE Arrows, BlockArguments #-} + +module BlockArgumentsArrowCmds where + +import Control.Arrow + +cmdLam :: () -> () +cmdLam = proc () -> (| id \() -> () >- returnA |) () + +cmdCase :: () -> () +cmdCase = proc () -> (| id case () of + () -> () >- returnA |) + +cmdIf :: () -> () +cmdIf = proc () -> (| id if True then () >- returnA else () >- returnA |) + +cmdLet :: () -> () +cmdLet = proc () -> (| id let x = () in x >- returnA |) + +cmdDo :: () -> () +cmdDo = proc () -> (| id do + () >- returnA |) ===================================== testsuite/tests/parser/should_compile/ParserArrowLambdaCase.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE Arrows, LambdaCase #-} +module ParserArrowLambdaCase where + +import Control.Arrow + +foo :: () -> () +foo = proc () -> (| id (\case + () -> () >- returnA) |) () ===================================== testsuite/tests/parser/should_compile/all.T ===================================== @@ -86,6 +86,7 @@ test('T3303', [], multimod_compile, ['T3303', '-v0']) test('T3741', normal, compile, ['']) test('DoAndIfThenElse', normal, compile, ['']) test('BlockArguments', normal, compile, ['']) +test('BlockArgumentsArrowCmds', normal, compile, ['']) test('BlockArgumentsLambdaCase', normal, compile, ['']) test('NoBlockArguments', normal, compile, ['']) test('NondecreasingIndentation', normal, compile, ['']) @@ -93,6 +94,7 @@ test('mc15', normal, compile, ['']) test('mc16', normal, compile, ['']) test('EmptyDecls', normal, compile, ['']) test('ParserLambdaCase', [], compile, ['']) +test('ParserArrowLambdaCase', [], compile, ['']) test('ColumnPragma', normal, compile, ['']) test('T5243', [], multimod_compile, ['T5243', '']) ===================================== testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE Arrows #-} +module NoBlockArgumentsFailArrowCmds where + +import Control.Arrow + +cmdLam :: () -> () +cmdLam = proc () -> (| id \() -> () >- returnA |) () ===================================== testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.stderr ===================================== @@ -0,0 +1,6 @@ + +NoBlockArgumentsFailArrowCmds.hs:7:27: error: + Unexpected lambda command in function application: + \ () -> () >- returnA + You could write it with parentheses + Or perhaps you meant to enable BlockArguments? ===================================== testsuite/tests/parser/should_fail/all.T ===================================== @@ -77,6 +77,7 @@ test('NoPatternSynonyms', normal, compile_fail, ['']) test('NoBlockArgumentsFail', normal, compile_fail, ['']) test('NoBlockArgumentsFail2', normal, compile_fail, ['']) test('NoBlockArgumentsFail3', normal, compile_fail, ['']) +test('NoBlockArgumentsFailArrowCmds', normal, compile_fail, ['']) test('NondecreasingIndentationFail', normal, compile_fail, ['']) test('readFailTraditionalRecords1', normal, compile_fail, ['']) test('readFailTraditionalRecords2', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8bfb0219587b969d5c8f723c46d433e9493958b4...f4d3773c7f4209cd3a0495ab9a29b978da48e2ff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8bfb0219587b969d5c8f723c46d433e9493958b4...f4d3773c7f4209cd3a0495ab9a29b978da48e2ff You're receiving 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 30 05:58:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 01:58:24 -0400 Subject: [Git][ghc/ghc][master] Add tests for #17873 Message-ID: <5eaa6900852a7_61673f81cc913ba07993520@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/T17873.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/T17873.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE ImplicitParams #-} + +module T17873 where + +-- With GHC 8.8 this failed with a nonsense message +-- Couldn't match type ‘?x::Bool -> Bool’ with ‘Bool’ +-- Expected type: Bool -> Bool -> Bool +-- Actual type: (?x::Bool -> Bool) => Bool -> Bool + +-- With eager instantiation, it's fine. + +getx :: (?x :: Bool -> Bool) => Bool -> Bool +getx = ?x + +z3 = (let ?x = not in getx) False ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -705,3 +705,4 @@ test('T18005', normal, compile, ['']) test('T18023', normal, compile, ['']) test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) +test('T17873', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5bdfdd139e5aff57631e9f1c6654dc7b8590c63f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5bdfdd139e5aff57631e9f1c6654dc7b8590c63f You're receiving 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 30 06:30:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 02:30:07 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 13 commits: Document backpack fields in DynFlags Message-ID: <5eaa706f1fc6a_61673f81cd9bfa6c799868a@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - cc358205 by Simon Peyton Jones at 2020-04-30T02:30:01-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - d8b44dad by Matthew Pickering at 2020-04-30T02:30:02-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b21d26e7143f7b0df675a5d01b8ac6b8d5adb916...d8b44dad5d0d417c86a2d65f14e53986fd499183 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b21d26e7143f7b0df675a5d01b8ac6b8d5adb916...d8b44dad5d0d417c86a2d65f14e53986fd499183 You're receiving 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 30 11:30:25 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 07:30:25 -0400 Subject: [Git][ghc/ghc][master] Mark rule args as non-tail-called Message-ID: <5eaab6d14aeb6_6167c5ce1b080577c3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 5 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Types/Basic.hs - + testsuite/tests/simplCore/should_compile/T18098.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -728,7 +728,7 @@ a right-hand side. In particular, we need to a) call 'markAllInsideLam' *unless* the binding is for a thunk, a one-shot lambda, or a non-recursive join point; and - b) call 'markAllNonTailCalled' *unless* the binding is for a join point. + b) call 'markAllNonTail' *unless* the binding is for a join point. Some examples, with how the free occurrences in e (assumed not to be a value lambda) get marked: @@ -1605,7 +1605,7 @@ occAnalUnfolding env mb_join_arity unf where env' = env `addInScope` bndrs (usage, args') = occAnalList env' args - final_usage = zapDetails (delDetailsList usage bndrs) + final_usage = markAllManyNonTail (delDetailsList usage bndrs) unf -> (emptyDetails, unf) @@ -1626,13 +1626,13 @@ occAnalRules env mb_join_arity bndr | otherwise = rule { ru_args = args', ru_rhs = rhs' } (lhs_uds, args') = occAnalList env' args - lhs_uds' = markAllMany $ + lhs_uds' = markAllManyNonTail $ lhs_uds `delDetailsList` bndrs (rhs_uds, rhs') = occAnal env' rhs -- Note [Rules are extra RHSs] -- Note [Rule dependency info] - rhs_uds' = markAllNonTailCalledIf (not exact_join) $ + rhs_uds' = markAllNonTailIf (not exact_join) $ markAllMany $ rhs_uds `delDetailsList` bndrs @@ -1758,7 +1758,7 @@ occAnal env (Tick tickish body) -- not the end of the world. | tickish `tickishScopesLike` SoftScope - = (markAllNonTailCalled usage, Tick tickish body') + = (markAllNonTail usage, Tick tickish body') | Breakpoint _ ids <- tickish = (usage_lam `andUDs` foldr addManyOcc emptyDetails ids, Tick tickish body') @@ -1769,7 +1769,7 @@ occAnal env (Tick tickish body) where !(usage,body') = occAnal env body -- for a non-soft tick scope, we can inline lambdas only - usage_lam = markAllNonTailCalled (markAllInsideLam usage) + usage_lam = markAllNonTail (markAllInsideLam usage) -- TODO There may be ways to make ticks and join points play -- nicer together, but right now there are problems: -- let j x = ... in tick (j 1) @@ -1780,13 +1780,13 @@ occAnal env (Tick tickish body) occAnal env (Cast expr co) = case occAnal env expr of { (usage, expr') -> - let usage1 = zapDetailsIf (isRhsEnv env) usage + let usage1 = markAllManyNonTailIf (isRhsEnv env) usage -- usage1: if we see let x = y `cast` co -- then mark y as 'Many' so that we don't -- immediately inline y again. usage2 = addManyOccs usage1 (coVarsOfCo co) -- usage2: see Note [Gather occurrences of coercion variables] - in (markAllNonTailCalled usage2, Cast expr' co) + in (markAllNonTail usage2, Cast expr' co) } occAnal env app@(App _ _) @@ -1799,7 +1799,7 @@ occAnal env app@(App _ _) occAnal env (Lam x body) | isTyVar x = case occAnal env body of { (body_usage, body') -> - (markAllNonTailCalled body_usage, Lam x body') + (markAllNonTail body_usage, Lam x body') } -- For value lambdas we do a special hack. Consider @@ -1815,7 +1815,7 @@ occAnal env expr@(Lam _ _) = case occAnalLamOrRhs env bndrs body of { (usage, tagged_bndrs, body') -> let expr' = mkLams tagged_bndrs body' - usage1 = markAllNonTailCalled usage + usage1 = markAllNonTail usage one_shot_gp = all isOneShotBndr tagged_bndrs final_usage = markAllInsideLamIf (not one_shot_gp) usage1 in @@ -1832,7 +1832,7 @@ occAnal env (Case scrut bndr ty alts) let alts_usage = foldr orUDs emptyDetails alts_usage_s (alts_usage1, tagged_bndr) = tagLamBinder alts_usage bndr - total_usage = markAllNonTailCalled scrut_usage `andUDs` alts_usage1 + total_usage = markAllNonTail scrut_usage `andUDs` alts_usage1 -- Alts can have tail calls, but the scrutinee can't in total_usage `seq` (total_usage, Case scrut' tagged_bndr ty alts') }} @@ -1893,7 +1893,7 @@ occAnalApp env (Var fun, args, ticks) all_uds = fun_uds `andUDs` final_args_uds !(args_uds, args') = occAnalArgs env args one_shots - !final_args_uds = markAllNonTailCalled $ + !final_args_uds = markAllNonTail $ markAllInsideLamIf (isRhsEnv env && is_exp) $ args_uds -- We mark the free vars of the argument of a constructor or PAP @@ -1923,7 +1923,7 @@ occAnalApp env (Var fun, args, ticks) -- See Note [Sources of one-shot information], bullet point A'] occAnalApp env (fun, args, ticks) - = (markAllNonTailCalled (fun_uds `andUDs` args_uds), + = (markAllNonTail (fun_uds `andUDs` args_uds), mkTicks ticks $ mkApps fun' args') where !(fun_uds, fun') = occAnal (addAppCtxt env args) fun @@ -2526,7 +2526,7 @@ data UsageDetails = UD { ud_env :: !OccInfoEnv , ud_z_many :: ZappedSet -- apply 'markMany' to these , ud_z_in_lam :: ZappedSet -- apply 'markInsideLam' to these - , ud_z_no_tail :: ZappedSet } -- apply 'markNonTailCalled' to these + , ud_z_no_tail :: ZappedSet } -- apply 'markNonTail' to these -- INVARIANT: All three zapped sets are subsets of the OccInfoEnv instance Outputable UsageDetails where @@ -2587,28 +2587,28 @@ emptyDetails = UD { ud_env = emptyVarEnv isEmptyDetails :: UsageDetails -> Bool isEmptyDetails = isEmptyVarEnv . ud_env -markAllMany, markAllInsideLam, markAllNonTailCalled, zapDetails +markAllMany, markAllInsideLam, markAllNonTail, markAllManyNonTail :: UsageDetails -> UsageDetails markAllMany ud = ud { ud_z_many = ud_env ud } markAllInsideLam ud = ud { ud_z_in_lam = ud_env ud } -markAllNonTailCalled ud = ud { ud_z_no_tail = ud_env ud } +markAllNonTail ud = ud { ud_z_no_tail = ud_env ud } -markAllInsideLamIf, markAllNonTailCalledIf :: Bool -> UsageDetails -> UsageDetails +markAllInsideLamIf, markAllNonTailIf :: Bool -> UsageDetails -> UsageDetails markAllInsideLamIf True ud = markAllInsideLam ud markAllInsideLamIf False ud = ud -markAllNonTailCalledIf True ud = markAllNonTailCalled ud -markAllNonTailCalledIf False ud = ud +markAllNonTailIf True ud = markAllNonTail ud +markAllNonTailIf False ud = ud -zapDetails = markAllMany . markAllNonTailCalled -- effectively sets to noOccInfo +markAllManyNonTail = markAllMany . markAllNonTail -- effectively sets to noOccInfo -zapDetailsIf :: Bool -- If this is true - -> UsageDetails -- Then do zapDetails on this +markAllManyNonTailIf :: Bool -- If this is true + -> UsageDetails -- Then do markAllManyNonTail on this -> UsageDetails -zapDetailsIf True uds = zapDetails uds -zapDetailsIf False uds = uds +markAllManyNonTailIf True uds = markAllManyNonTail uds +markAllManyNonTailIf False uds = uds lookupDetails :: UsageDetails -> Id -> OccInfo lookupDetails ud id @@ -2674,7 +2674,7 @@ doZappingByUnique (UD { ud_z_many = many occ1 | uniq `elemVarEnvByKey` many = markMany occ | uniq `elemVarEnvByKey` in_lam = markInsideLam occ | otherwise = occ - occ2 | uniq `elemVarEnvByKey` no_tail = markNonTailCalled occ1 + occ2 | uniq `elemVarEnvByKey` no_tail = markNonTail occ1 | otherwise = occ1 alterZappedSets :: UsageDetails -> (ZappedSet -> ZappedSet) -> UsageDetails @@ -2700,7 +2700,7 @@ adjustRhsUsage :: Maybe JoinArity -> RecFlag -> UsageDetails adjustRhsUsage mb_join_arity rec_flag bndrs usage = markAllInsideLamIf (not one_shot) $ - markAllNonTailCalledIf (not exact_join) $ + markAllNonTailIf (not exact_join) $ usage where one_shot = case mb_join_arity of @@ -2738,7 +2738,7 @@ tagLamBinder usage bndr = (usage2, bndr') where occ = lookupDetails usage bndr - bndr' = setBinderOcc (markNonTailCalled occ) bndr + bndr' = setBinderOcc (markNonTail occ) bndr -- Don't try to make an argument into a join point usage1 = usage `delDetails` bndr usage2 | isId bndr = addManyOccs usage1 (idUnfoldingVars bndr) @@ -2759,7 +2759,7 @@ tagNonRecBinder lvl usage binder will_be_join = decideJoinPointHood lvl usage [binder] occ' | will_be_join = -- must already be marked AlwaysTailCalled ASSERT(isAlwaysTailCalled occ) occ - | otherwise = markNonTailCalled occ + | otherwise = markNonTail occ binder' = setBinderOcc occ' binder usage' = usage `delDetails` binder in @@ -2930,7 +2930,7 @@ See Invariant 2a of Note [Invariants on join points] in GHC.Core ************************************************************************ -} -markMany, markInsideLam, markNonTailCalled :: OccInfo -> OccInfo +markMany, markInsideLam, markNonTail :: OccInfo -> OccInfo markMany IAmDead = IAmDead markMany occ = ManyOccs { occ_tail = occ_tail occ } @@ -2938,8 +2938,8 @@ markMany occ = ManyOccs { occ_tail = occ_tail occ } markInsideLam occ@(OneOcc {}) = occ { occ_in_lam = IsInsideLam } markInsideLam occ = occ -markNonTailCalled IAmDead = IAmDead -markNonTailCalled occ = occ { occ_tail = NoTailCallInfo } +markNonTail IAmDead = IAmDead +markNonTail occ = occ { occ_tail = NoTailCallInfo } addOccInfo, orOccInfo :: OccInfo -> OccInfo -> OccInfo ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -446,7 +446,7 @@ pprIdBndrInfo info lbv_info = oneShotInfo info has_prag = not (isDefaultInlinePragma prag_info) - has_occ = not (isManyOccs occ_info) + has_occ = not (isNoOccInfo occ_info) has_dmd = not $ isTopDmd dmd_info has_lbv = not (hasNoOneShotInfo lbv_info) ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -67,7 +67,7 @@ module GHC.Types.Basic ( OccInfo(..), noOccInfo, seqOccInfo, zapFragileOcc, isOneOcc, isDeadOcc, isStrongLoopBreaker, isWeakLoopBreaker, isManyOccs, - strongLoopBreaker, weakLoopBreaker, + isNoOccInfo, strongLoopBreaker, weakLoopBreaker, InsideLam(..), OneBranch(..), @@ -958,6 +958,10 @@ See OccurAnal Note [Weak loop breakers] noOccInfo :: OccInfo noOccInfo = ManyOccs { occ_tail = NoTailCallInfo } +isNoOccInfo :: OccInfo -> Bool +isNoOccInfo ManyOccs { occ_tail = NoTailCallInfo } = True +isNoOccInfo _ = False + isManyOccs :: OccInfo -> Bool isManyOccs ManyOccs{} = True isManyOccs _ = False ===================================== testsuite/tests/simplCore/should_compile/T18098.hs ===================================== @@ -0,0 +1,78 @@ +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE KindSignatures #-} +module Bug where + +import Control.Monad.ST (runST, ST) +import Data.Kind (Type) +import Data.Functor.Identity (Identity(..)) + +gcons :: (GVector v a) => a -> Stream Identity (Chunk v a) -> v a +gcons x tb = gmvmunstreamUnknown $ sappend (ssingleton x) tb +{-# INLINE gcons #-} + +data Chunk v a = MkChunk (forall s. GVector v a => Mutable v s a -> ST s ()) + +data Step s a = Yield a s | Done + +data Stream m a = forall s. Stream (s -> m (Step s a)) s + +data Mutable :: (Type -> Type) -> Type -> Type -> Type + +class GVector v a where + gmbasicLength :: Mutable v s a -> Int + gmbasicUnsafeSlice :: Mutable v s a -> Mutable v s a + gmbasicUnsafeNew :: ST s (Mutable v s a) + gmbasicUnsafeWrite :: a -> Mutable v s a -> ST s () + gmbasicUnsafeGrow :: Mutable v s a -> Int -> m (Mutable v s a) + gbasicUnsafeFreeze :: Mutable v s a -> ST s (v a) + +sfoldlM :: (a -> b -> ST s a) -> (t -> Step t b) -> a -> t -> ST s a +sfoldlM m step = foldlM_loop + where + foldlM_loop z s + = case step s of + Yield x s' -> do { z' <- m z x; foldlM_loop z' s' } + Done -> return z +{-# INLINE [1] sfoldlM #-} + +sappend :: Stream Identity a -> Stream Identity a -> Stream Identity a +Stream stepa ta `sappend` Stream stepb _ = Stream step (Left ta) + where + {-# INLINE [0] step #-} + step (Left sa) = do + r <- stepa sa + return $ case r of + Yield x _ -> Yield x (Left sa) + Done -> Done + step (Right sb) = do + r <- stepb sb + return $ case r of + Yield x _ -> Yield x (Right sb) + Done -> Done +{-# INLINE [1] sappend #-} + +ssingleton :: Monad m => a -> Stream m (Chunk v a) +ssingleton x = Stream (return . step) True + where + {-# INLINE [0] step #-} + step True = Yield (MkChunk (gmbasicUnsafeWrite x)) False + step False = Done +{-# INLINE [1] ssingleton #-} + +gmvmunstreamUnknown :: GVector v a => Stream Identity (Chunk v a) -> v a +gmvmunstreamUnknown (Stream vstep u) + = runST (do + v <- gmbasicUnsafeNew + sfoldlM copyChunk (runIdentity . vstep) (v,0) u + gbasicUnsafeFreeze v) + where + {-# INLINE [0] copyChunk #-} + copyChunk (v,i) (MkChunk f) + = do + v' <- gmbasicUnsafeGrow v (gmbasicLength v) + f (gmbasicUnsafeSlice v') + return (v',i) +{-# INLINE gmvmunstreamUnknown #-} ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -317,3 +317,4 @@ test('T17966', # NB: T17810: -fspecialise-aggressively test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) +test('T18098', normal, compile, ['-dcore-lint -O2']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19b701c216246596710f0eba112ed5ee7b6bf870 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19b701c216246596710f0eba112ed5ee7b6bf870 You're receiving 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 30 11:31:00 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 07:31:00 -0400 Subject: [Git][ghc/ghc][master] Hadrian: Improve tool-args command to support more components Message-ID: <5eaab6f43bfca_6167120888bc8061120@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 6 changed files: - hadrian/ghci-cabal - hadrian/ghci-stack - hadrian/hadrian.cabal - hadrian/hie-bios - hadrian/src/Rules.hs - + hadrian/src/Rules/ToolArgs.hs Changes: ===================================== hadrian/ghci-cabal ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" -ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool:ghc/Main.hs -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" +ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m ===================================== hadrian/ghci-stack ===================================== @@ -4,4 +4,4 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" -stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m ===================================== hadrian/hadrian.cabal ===================================== @@ -77,6 +77,7 @@ executable hadrian , Rules.Program , Rules.Register , Rules.Rts + , Rules.ToolArgs , Rules.Selftest , Rules.SimpleTargets , Rules.SourceDist ===================================== hadrian/hie-bios ===================================== @@ -3,7 +3,5 @@ # When run, this program will output a list of arguments which are necessary to # load the GHC library component into GHCi. The program is used by `ghcide` in # order to automatically set up the correct GHC API session for a project. -TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool-args -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT -echo -ighc >> $HIE_BIOS_OUTPUT -echo "ghc/Main.hs" >> $HIE_BIOS_OUTPUT +TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool:$1 -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT ===================================== hadrian/src/Rules.hs ===================================== @@ -24,43 +24,12 @@ import qualified Rules.Program import qualified Rules.Register import qualified Rules.Rts import qualified Rules.SimpleTargets +import Rules.ToolArgs import Settings import Settings.Program (programContext) import Target import UserSettings --- | @tool-args@ is used by tooling in order to get the arguments necessary --- to set up a GHC API session which can compile modules from GHC. When --- run, the target prints out the arguments that would be passed to @ghc@ --- during normal compilation to @stdout at . --- --- This target is called by the `ghci` script in order to load all of GHC's --- modules into GHCi. -toolArgsTarget :: Rules () -toolArgsTarget = do - "tool-args" ~> do - -- We can't build DLLs on Windows (yet). Actually we should only - -- include the dynamic way when we have a dynamic host GHC, but just - -- checking for Windows seems simpler for now. - let fake_target = target (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) - (Ghc ToolArgs Stage0) [] ["ignored"] - - -- need the autogenerated files so that they are precompiled - includesDependencies Stage0 >>= need - interpret fake_target Rules.Generate.compilerDependencies >>= need - - root <- buildRoot - let dir = buildDir (vanillaContext Stage0 compiler) - need [ root -/- dir -/- "Config.hs" ] - need [ root -/- dir -/- "GHC" -/- "Parser.hs" ] - need [ root -/- dir -/- "GHC" -/- "Parser" -/- "Lexer.hs" ] - need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Parser.hs" ] - need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Lexer.hs" ] - - -- Find out the arguments that are needed to load a module into the - -- session - arg_list <- interpret fake_target getArgs - liftIO $ putStrLn (intercalate "\n" arg_list) allStages :: [Stage] allStages = [minBound .. maxBound] ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -0,0 +1,128 @@ +module Rules.ToolArgs(toolArgsTarget) where + +import qualified Rules.Generate +import Development.Shake +import Target +import Context +import Stage +import Expression + +import Packages +import Settings +import Hadrian.Oracles.Cabal +import Hadrian.Haskell.Cabal.Type +import System.Directory (canonicalizePath) + +-- | @tool:@ is used by tooling in order to get the arguments necessary +-- to set up a GHC API session which can compile modules from GHC. When +-- run, the target prints out the arguments that would be passed to @ghc@ +-- during normal compilation to @stdout@ for the file passed as an +-- argument. +-- +-- This target is called by the `ghci.sh` script in order to load all of GHC's +-- modules into GHCi. It is invoked with argument `tool:ghc/Main.hs` in +-- that script so that we can load the whole library and executable +-- components into GHCi. +-- +-- In the future where we have multi-component ghci this code can be +-- modified to supply the right arguments for that. At the moment it is +-- also used for GHC's support for multi-component ghcide (see the +-- `hadrian/hie-bios` script). + + +-- | A phony target of form `tool:path/to/file.hs` which returns the +-- options needed to compile the specific file. +toolArgsTarget :: Rules () +toolArgsTarget = do + phonys (\s -> if "tool:" `isPrefixOf` s then Just (toolRuleBody (drop 5 s)) else Nothing) + +toolRuleBody :: FilePath -> Action () +toolRuleBody fp = do + mm <- dirMap + cfp <- liftIO $ canonicalizePath fp + case find (flip isPrefixOf cfp . fst) mm of + Just (_, (p, extra)) -> mkToolTarget extra p + Nothing -> fail $ "No prefixes matched " ++ show fp ++ " IN\n " ++ show mm + +mkToolTarget :: [String] -> Package -> Action () +mkToolTarget es p = do + -- This builds automatically generated dependencies. Not sure how to do + -- this generically yet. + allDeps + let fake_target = target (Context Stage0 p (if windowsHost then vanilla else dynamic)) + (Ghc ToolArgs Stage0) [] ["ignored"] + arg_list <- interpret fake_target getArgs + liftIO $ putStrLn (intercalate "\n" (arg_list ++ es)) +allDeps :: Action () +allDeps = do + do + -- We can't build DLLs on Windows (yet). Actually we should only + -- include the dynamic way when we have a dynamic host GHC, but just + -- checking for Windows seems simpler for now. + let fake_target = target (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) + (Ghc ToolArgs Stage0) [] ["ignored"] + + -- need the autogenerated files so that they are precompiled + includesDependencies Stage0 >>= need + interpret fake_target Rules.Generate.compilerDependencies >>= need + + root <- buildRoot + let dir = buildDir (vanillaContext Stage0 compiler) + need [ root -/- dir -/- "Config.hs" ] + need [ root -/- dir -/- "GHC" -/- "Parser.hs" ] + need [ root -/- dir -/- "GHC" -/- "Parser" -/- "Lexer.hs" ] + need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Parser.hs" ] + need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Lexer.hs" ] + +-- This list is quite a lot like stage0packages but doesn't include +-- critically the `exe:ghc` component as that depends on the GHC library +-- which takes a while to compile. +toolTargets :: [Package] +toolTargets = [ array + , bytestring + , templateHaskell + , containers + , deepseq + , directory + , exceptions + , filepath + , compiler + , ghcCompact + , ghcPrim + --, haskeline + , hp2ps + , hsc2hs + , pretty + , process + , rts + , stm + , time + , unlit + , xhtml ] + +-- | Create a mapping from files to which component it belongs to. +dirMap :: Action [(FilePath, (Package, [String]))] +dirMap = do + auto <- concatMapM go toolTargets + -- Mush the ghc executable into the compiler component so the whole of ghc is not built when + -- configuring + ghc_exe <- mkGhc + return (auto ++ [ghc_exe]) + + where + -- Make a separate target for the exe:ghc target because otherwise + -- configuring would build the whole GHC library which we probably + -- don't want to do. + mkGhc = do + let c = (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) + cd <- readContextData c + fp <- liftIO $ canonicalizePath "ghc/" + return (fp, (compiler, "-ighc" : modules cd ++ otherModules cd ++ ["ghc/Main.hs"])) + go p = do + let c = (Context Stage0 p (if windowsHost then vanilla else dynamic)) + -- readContextData has the effect of configuring the package so all + -- dependent packages will also be built. + cd <- readContextData c + ids <- liftIO $ mapM canonicalizePath [pkgPath p i | i <- srcDirs cd] + return $ map (,(p, modules cd ++ otherModules cd)) ids + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/014ef4a3d9ee30b8add9118950f1f5007143bd1c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/014ef4a3d9ee30b8add9118950f1f5007143bd1c You're receiving 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 30 13:41:17 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 30 Apr 2020 09:41:17 -0400 Subject: [Git][ghc/ghc][wip/T18049] PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info Message-ID: <5eaad57dba40b_6167e5b152c809797e@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18049 at Glasgow Haskell Compiler / GHC Commits: fdb3f9ae by Sebastian Graf at 2020-04-30T15:41:07+02:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 6 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Tc/Types/Evidence.hs - + testsuite/tests/pmcheck/should_compile/T18049.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -33,7 +33,7 @@ import {-# SOURCE #-} GHC.HsToCore.Match ( matchWrapper ) import GHC.HsToCore.Monad import GHC.HsToCore.GuardedRHSs import GHC.HsToCore.Utils -import GHC.HsToCore.PmCheck ( needToRunPmCheck, addTyCsDs, checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Hs -- lots of things import GHC.Core -- lots of things @@ -145,12 +145,20 @@ dsHsBind dflags (VarBind { var_id = var else [] ; return (force_var, [core_bind]) } -dsHsBind dflags b@(FunBind { fun_id = L _ fun +dsHsBind dflags b@(FunBind { fun_id = L loc fun , fun_matches = matches , fun_ext = co_fn , fun_tick = tick }) - = do { (args, body) <- matchWrapper - (mkPrefixFunRhs (noLoc $ idName fun)) + = do { (args, body) <- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + -- FromSource might not be accurate (we don't have any + -- origin annotations for things in this module), but at + -- worst we do superfluous calls to the pattern match + -- oracle. + -- addTyCsDs: Add type evidence to the refinement type + -- predicate of the coverage checker + -- See Note [Type and Term Equality Propagation] in PmCheck + matchWrapper + (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body @@ -189,15 +197,7 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts , abs_exports = exports , abs_ev_binds = ev_binds , abs_binds = binds, abs_sig = has_sig }) - = do { ds_binds <- applyWhen (needToRunPmCheck dflags FromSource) - -- FromSource might not be accurate, but at worst - -- we do superfluous calls to the pattern match - -- oracle. - -- addTyCsDs: push type constraints deeper - -- for inner pattern match check - -- See Check, Note [Type and Term Equality Propagation] - (addTyCsDs (listToBag dicts)) - (dsLHsBinds binds) + = do { ds_binds <- addTyCsDs FromSource (listToBag dicts) (dsLHsBinds binds) ; ds_ev_binds <- dsTcEvBinds_s ev_binds @@ -206,7 +206,6 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind" - ----------------------- dsAbsBinds :: DynFlags -> [TyVar] -> [EvVar] -> [ABExport GhcTc] ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.HsToCore.ListComp import GHC.HsToCore.Utils import GHC.HsToCore.Arrows import GHC.HsToCore.Monad -import GHC.HsToCore.PmCheck ( checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Types.Name import GHC.Types.Name.Env import GHC.Core.FamInstEnv( topNormaliseType ) @@ -280,7 +280,8 @@ dsExpr hswrap@(XExpr (HsWrap co_fn e)) HsConLikeOut _ (RealDataCon dc) -> return $ varToCoreExpr (dataConWrapId dc) XExpr (HsWrap _ _) -> pprPanic "dsExpr: HsWrap inside HsWrap" (ppr hswrap) HsPar _ _ -> pprPanic "dsExpr: HsPar inside HsWrap" (ppr hswrap) - _ -> dsExpr e + _ -> addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + dsExpr e -- See Note [Detecting forced eta expansion] ; wrap' <- dsHsWrapper co_fn ; dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -14,7 +14,7 @@ Pattern Matching Coverage Checking. module GHC.HsToCore.PmCheck ( -- Checking and printing checkSingle, checkMatches, checkGuardMatches, - needToRunPmCheck, isMatchContextPmChecked, + isMatchContextPmChecked, -- See Note [Type and Term Equality Propagation] addTyCsDs, addScrutTmCs @@ -45,7 +45,7 @@ import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Types.Var (EvVar) import GHC.Core.Coercion -import GHC.Tc.Types.Evidence ( HsWrapper(..), isIdHsWrapper ) +import GHC.Tc.Types.Evidence (HsWrapper(..), isIdHsWrapper) import GHC.Tc.Utils.TcType (evVarPred) import {-# SOURCE #-} GHC.HsToCore.Expr (dsExpr, dsLExpr, dsSyntaxExpr) import {-# SOURCE #-} GHC.HsToCore.Binds (dsHsWrapper) @@ -53,6 +53,7 @@ import GHC.HsToCore.Utils (selectMatchVar) import GHC.HsToCore.Match.Literal (dsLit, dsOverLit) import GHC.HsToCore.Monad import GHC.Data.Bag +import GHC.Data.IOEnv (unsafeInterleaveM) import GHC.Data.OrdList import GHC.Core.TyCo.Rep import GHC.Core.Type @@ -1033,20 +1034,30 @@ Functions `addScrutTmCs' is responsible for generating these constraints. -} +-- | Locally update 'dsl_deltas' with the given action, but defer evaluation +-- with 'unsafeInterleaveM' in order not to do unnecessary work. locallyExtendPmDelta :: (Deltas -> DsM Deltas) -> DsM a -> DsM a -locallyExtendPmDelta ext k = getPmDeltas >>= ext >>= \deltas -> do - inh <- isInhabited deltas - -- If adding a constraint would lead to a contradiction, don't add it. - -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ - -- for why this is done. - if inh - then updPmDeltas deltas k - else k - --- | Add in-scope type constraints -addTyCsDs :: Bag EvVar -> DsM a -> DsM a -addTyCsDs ev_vars = - locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars)) +locallyExtendPmDelta ext k = do + deltas <- getPmDeltas + deltas' <- unsafeInterleaveM $ do + deltas' <- ext deltas + inh <- isInhabited deltas' + -- If adding a constraint would lead to a contradiction, don't add it. + -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ + -- for why this is done. + if inh + then pure deltas' + else pure deltas + updPmDeltas deltas' k + +-- | Add in-scope type constraints if the coverage checker might run and then +-- run the given action. +addTyCsDs :: Origin -> Bag EvVar -> DsM a -> DsM a +addTyCsDs origin ev_vars m = do + dflags <- getDynFlags + applyWhen (needToRunPmCheck dflags origin) + (locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars))) + m -- | Add equalities for the scrutinee to the local 'DsM' environment when -- checking a case expression: ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -10,7 +10,7 @@ module GHC.Tc.Types.Evidence ( (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, - pprHsWrapper, + pprHsWrapper, hsWrapDictBinders, -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), @@ -370,6 +370,27 @@ isErasableHsWrapper = go go WpTyApp{} = True go WpLet{} = False +hsWrapDictBinders :: HsWrapper -> Bag DictId +-- ^ Identifies the /lambda-bound/ dictionaries of an 'HsWrapper'. This is used +-- (only) to allow the pattern-match overlap checker to know what Given +-- dictionaries are in scope. +-- +-- We specifically do not collect dictionaries bound in a 'WpLet'. These are +-- either superclasses of lambda-bound ones, or (extremely numerous) results of +-- binding Wanted dictionaries. We definitely don't want all those cluttering +-- up the Given dictionaries for pattern-match overlap checking! +hsWrapDictBinders wrap = go wrap + where + go (WpEvLam dict_id) = unitBag dict_id + go (w1 `WpCompose` w2) = go w1 `unionBags` go w2 + go (WpFun _ w _ _) = go w + go WpHole = emptyBag + go (WpCast {}) = emptyBag + go (WpEvApp {}) = emptyBag + go (WpTyLam {}) = emptyBag + go (WpTyApp {}) = emptyBag + go (WpLet {}) = emptyBag + collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, -- stopping as soon as you get to a non-lambda binder ===================================== testsuite/tests/pmcheck/should_compile/T18049.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +module Bug where + +import Data.Kind + +data SBool :: Bool -> Type where + SFalse :: SBool False + STrue :: SBool True + +f :: SBool b + -> (b ~ True => SBool b -> r) + -> (b ~ False => SBool b -> r) + -> r +f x t f = + case x of + SFalse -> f x + STrue -> t x + +g :: forall b. SBool b -> () +g x = f x + (\x' -> + case x' of + -- SFalse -> () + STrue -> ()) + (\_ -> ()) ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -118,6 +118,8 @@ test('T17977', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17977b', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T18049', normal, compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdb3f9ae156f8d66f6918396aebdb743a72e5228 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdb3f9ae156f8d66f6918396aebdb743a72e5228 You're receiving 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 30 14:35:11 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Thu, 30 Apr 2020 10:35:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/the-flattening-story Message-ID: <5eaae21f766e1_6167122e22ac811404f@gitlab.haskell.org.mail> Richard Eisenberg pushed new branch wip/the-flattening-story at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/the-flattening-story You're receiving 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 30 16:02:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 30 Apr 2020 12:02:17 -0400 Subject: [Git][ghc/ghc][wip/T17609] nativeGen: Deduplicate DWARF strings Message-ID: <5eaaf689ec36d_616787c09cc813302b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17609 at Glasgow Haskell Compiler / GHC Commits: a78ef103 by Ben Gamari at 2020-04-30T12:02:11-04:00 nativeGen: Deduplicate DWARF strings As noted in #17609, we previously made no attempt to deduplicate strings. This resulted in unnecessarily long compile times and large object files. Fix this. Fixes #17609. - - - - - 3 changed files: - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Dwarf/Types.hs Changes: ===================================== compiler/GHC/CmmToAsm/Dwarf.hs ===================================== @@ -10,9 +10,10 @@ import Config ( cProjectName, cProjectVersion ) import GHC.Core ( Tickish(..) ) import GHC.Cmm.DebugBlock import GHC.Driver.Session -import GHC.Types.Module import Outputable import GHC.Platform +import GHC.Types.Module +import GHC.Types.SrcLoc import GHC.Types.Unique import GHC.Types.Unique.Supply @@ -47,11 +48,12 @@ dwarfGen df modLoc us blocks = do compPath <- getCurrentDirectory let lowLabel = dblCLabel $ head procs highLabel = mkAsmTempEndLabel $ dblCLabel $ last procs + producer = dwarfStringFromString $ cProjectName ++ " " ++ cProjectVersion dwarfUnit = DwarfCompileUnit { dwChildren = map (procToDwarf df) (map stripBlocks procs) - , dwName = fromMaybe "" (ml_hs_file modLoc) - , dwCompDir = addTrailingPathSeparator compPath - , dwProducer = cProjectName ++ " " ++ cProjectVersion + , dwName = dwarfStringFromString $ fromMaybe "" (ml_hs_file modLoc) + , dwCompDir = dwarfStringFromString $ addTrailingPathSeparator compPath + , dwProducer = producer , dwLowLabel = lowLabel , dwHighLabel = highLabel , dwLineLabel = dwarfLineLabel @@ -77,6 +79,9 @@ dwarfGen df modLoc us blocks = do , compileUnitFooter unitU ] + -- .debug_str section: Strings + let stringsSct = dwarfStringsSection (dwarfInfoStrings dwarfUnit) + -- .debug_line section: Generated mainly by the assembler, but we -- need to label it let lineSct = dwarfLineSection platform $$ @@ -93,7 +98,7 @@ dwarfGen df modLoc us blocks = do | otherwise = [DwarfARange lowLabel highLabel] let aranges = dwarfARangesSection platform $$ pprDwarfARanges platform aranges' unitU - return (infoSct $$ abbrevSct $$ lineSct $$ frameSct $$ aranges, us'') + return (infoSct $$ stringsSct $$ abbrevSct $$ lineSct $$ frameSct $$ aranges, us'') -- | Build an address range entry for one proc. -- With split sections, each proc needs its own entry, since they may get @@ -178,7 +183,7 @@ parent, B. procToDwarf :: DynFlags -> DebugBlock -> DwarfInfo procToDwarf df prc = DwarfSubprogram { dwChildren = map blockToDwarf (dblBlocks prc) - , dwName = case dblSourceTick prc of + , dwName = dwarfStringFromString $ case dblSourceTick prc of Just s at SourceNote{} -> sourceName s _otherwise -> showSDocDump df $ ppr $ dblLabel prc , dwLabel = dblCLabel prc @@ -209,7 +214,13 @@ blockToDwarf blk | otherwise = Nothing -- block was optimized out tickToDwarf :: Tickish () -> [DwarfInfo] -tickToDwarf (SourceNote ss _) = [DwarfSrcNote ss] +tickToDwarf (SourceNote ss _) = + [DwarfSrcNote { dwSpanFile = dwarfStringFromFastString (srcSpanFile ss) + , dwSpanStartLine = srcSpanStartLine ss + , dwSpanStartCol = srcSpanStartCol ss + , dwSpanEndLine = srcSpanEndLine ss + , dwSpanEndCol = srcSpanEndCol ss + }] tickToDwarf _ = [] -- | Generates the data for the debug frame section, which encodes the ===================================== compiler/GHC/CmmToAsm/Dwarf/Constants.hs ===================================== @@ -86,12 +86,14 @@ dW_CHILDREN_no, dW_CHILDREN_yes :: Word8 dW_CHILDREN_no = 0 dW_CHILDREN_yes = 1 -dW_FORM_addr, dW_FORM_data2, dW_FORM_data4, dW_FORM_string, dW_FORM_flag, +dW_FORM_addr, dW_FORM_data2, dW_FORM_data4, + dW_FORM_strp,dW_FORM_string, dW_FORM_flag, dW_FORM_block1, dW_FORM_ref4, dW_FORM_ref_addr, dW_FORM_flag_present :: Word dW_FORM_addr = 0x01 dW_FORM_data2 = 0x05 dW_FORM_data4 = 0x06 dW_FORM_string = 0x08 +dW_FORM_strp = 0x0e dW_FORM_flag = 0x0c dW_FORM_block1 = 0x0a dW_FORM_ref_addr = 0x10 ===================================== compiler/GHC/CmmToAsm/Dwarf/Types.hs ===================================== @@ -1,8 +1,16 @@ +{-# LANGUAGE RecordWildCards #-} + module GHC.CmmToAsm.Dwarf.Types ( -- * Dwarf information DwarfInfo(..) , pprDwarfInfo , pprAbbrevDecls + , dwarfInfoStrings + -- * Dwarf Strings section + , DwarfString + , dwarfStringsSection + , dwarfStringFromString + , dwarfStringFromFastString -- * Dwarf address range table , DwarfARange(..) , pprDwarfARanges @@ -27,18 +35,14 @@ import GhcPrelude import GHC.Cmm.DebugBlock import GHC.Cmm.CLabel import GHC.Cmm.Expr ( GlobalReg(..) ) -import Encoding import FastString import Outputable import GHC.Platform import GHC.Types.Unique import GHC.Platform.Reg -import GHC.Types.SrcLoc -import Util import GHC.CmmToAsm.Dwarf.Constants -import qualified Data.ByteString as BS import qualified Control.Monad.Trans.State.Strict as S import Control.Monad (zipWithM, join) import Data.Bits @@ -48,18 +52,46 @@ import Data.Char import GHC.Platform.Regs +-- | A string in the DWARF @.debug_str@ section. +newtype DwarfString = DwarfString FastString + +dwarfStringFromString :: String -> DwarfString +dwarfStringFromString = dwarfStringFromFastString . fsLit + +dwarfStringFromFastString :: FastString -> DwarfString +dwarfStringFromFastString = DwarfString + +dwarfStringSymbol :: DwarfString -> SDoc +dwarfStringSymbol (DwarfString fs) = + text "_dbgfs_" <> ppr (getUnique fs) + +debugStrSection :: SDoc +debugStrSection = text ".debug_str" + +pprDwarfString :: Platform -> DwarfString -> SDoc +pprDwarfString plat s = + sectionOffset plat (dwarfStringSymbol s) debugStrSection + +dwarfStringsSection :: [DwarfString] -> SDoc +dwarfStringsSection xs = + text ".section" <+> debugStrSection $$ hcat (map string xs) + where + string :: DwarfString -> SDoc + string dstr@(DwarfString fstr) = + dwarfStringSymbol dstr <> colon $$ pprFastString fstr + -- | Individual dwarf records. Each one will be encoded as an entry in -- the @.debug_info@ section. data DwarfInfo = DwarfCompileUnit { dwChildren :: [DwarfInfo] - , dwName :: String - , dwProducer :: String - , dwCompDir :: String + , dwName :: DwarfString + , dwProducer :: DwarfString + , dwCompDir :: DwarfString , dwLowLabel :: CLabel , dwHighLabel :: CLabel , dwLineLabel :: PtrString } | DwarfSubprogram { dwChildren :: [DwarfInfo] - , dwName :: String + , dwName :: DwarfString , dwLabel :: CLabel , dwParent :: Maybe CLabel -- ^ label of DIE belonging to the parent tick @@ -68,9 +100,23 @@ data DwarfInfo , dwLabel :: CLabel , dwMarker :: Maybe CLabel } - | DwarfSrcNote { dwSrcSpan :: RealSrcSpan + | DwarfSrcNote { dwSpanFile :: !DwarfString + , dwSpanStartLine :: !Int + , dwSpanStartCol :: !Int + , dwSpanEndLine :: !Int + , dwSpanEndCol :: !Int } +-- | 'DwarfStrings' mentioned by the given 'DwarfInfo'. +dwarfInfoStrings :: DwarfInfo -> [DwarfString] +dwarfInfoStrings dwinfo = + case dwinfo of + DwarfCompileUnit {..} -> [dwName, dwProducer, dwCompDir] ++ foldMap dwarfInfoStrings dwChildren + DwarfSubprogram {..} -> [dwName] ++ foldMap dwarfInfoStrings dwChildren + DwarfBlock {..} -> foldMap dwarfInfoStrings dwChildren + DwarfSrcNote {..} -> [dwSpanFile] + + -- | Abbreviation codes used for encoding above records in the -- @.debug_info@ section. data DwarfAbbrev @@ -133,7 +179,7 @@ pprAbbrevDecls platform haveDebugLine = , (dW_AT_high_pc, dW_FORM_addr) ] $$ mkAbbrev DwAbbrGhcSrcNote dW_TAG_ghc_src_note dW_CHILDREN_no - [ (dW_AT_ghc_span_file, dW_FORM_string) + [ (dW_AT_ghc_span_file, dW_FORM_strp) , (dW_AT_ghc_span_start_line, dW_FORM_data4) , (dW_AT_ghc_span_start_col, dW_FORM_data2) , (dW_AT_ghc_span_end_line, dW_FORM_data4) @@ -163,10 +209,10 @@ pprDwarfInfoOpen :: Platform -> Bool -> DwarfInfo -> SDoc pprDwarfInfoOpen platform haveSrc (DwarfCompileUnit _ name producer compDir lowLabel highLabel lineLbl) = pprAbbrev DwAbbrCompileUnit - $$ pprString name - $$ pprString producer + $$ pprDwarfString platform name + $$ pprDwarfString platform producer $$ pprData4 dW_LANG_Haskell - $$ pprString compDir + $$ pprDwarfString platform compDir $$ pprWord platform (ppr lowLabel) $$ pprWord platform (ppr highLabel) $$ if haveSrc @@ -176,7 +222,7 @@ pprDwarfInfoOpen platform _ (DwarfSubprogram _ name label parent) = sdocWithDynFlags $ \df -> ppr (mkAsmTempDieLabel label) <> colon $$ pprAbbrev abbrev - $$ pprString name + $$ pprDwarfString platform name $$ pprString (renderWithStyle (initSDocContext df (mkCodeStyle CStyle)) (ppr label)) $$ pprFlag (externallyVisibleCLabel label) $$ pprWord platform (ppr label) @@ -199,13 +245,13 @@ pprDwarfInfoOpen platform _ (DwarfBlock _ label (Just marker)) = sdocWithDynFlag $$ pprString (renderWithStyle (initSDocContext df (mkCodeStyle CStyle)) (ppr label)) $$ pprWord platform (ppr marker) $$ pprWord platform (ppr $ mkAsmTempEndLabel marker) -pprDwarfInfoOpen _ _ (DwarfSrcNote ss) = +pprDwarfInfoOpen platform _ (DwarfSrcNote {..}) = pprAbbrev DwAbbrGhcSrcNote - $$ pprString' (ftext $ srcSpanFile ss) - $$ pprData4 (fromIntegral $ srcSpanStartLine ss) - $$ pprHalf (fromIntegral $ srcSpanStartCol ss) - $$ pprData4 (fromIntegral $ srcSpanEndLine ss) - $$ pprHalf (fromIntegral $ srcSpanEndCol ss) + $$ pprDwarfString platform dwSpanFile + $$ pprData4 (fromIntegral dwSpanStartLine) + $$ pprHalf (fromIntegral dwSpanStartCol) + $$ pprData4 (fromIntegral dwSpanEndLine) + $$ pprHalf (fromIntegral dwSpanEndCol) -- | Close a DWARF info record with children pprDwarfInfoClose :: SDoc @@ -573,13 +619,13 @@ pprLEBInt x | x >= -64 && x < 64 pprString' :: SDoc -> SDoc pprString' str = text "\t.asciz \"" <> str <> char '"' +-- | Generate a string constant. We take care to escape the string. +pprFastString :: FastString -> SDoc +pprFastString = pprString' . hcat . map escapeChar . unpackFS + -- | Generate a string constant. We take care to escape the string. pprString :: String -> SDoc -pprString str - = pprString' $ hcat $ map escapeChar $ - if str `lengthIs` utf8EncodedLength str - then str - else map (chr . fromIntegral) $ BS.unpack $ bytesFS $ mkFastString str +pprString = pprFastString . mkFastString -- | Escape a single non-unicode character escapeChar :: Char -> SDoc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a78ef103f9c95f28929082f4fa402c684445b81f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a78ef103f9c95f28929082f4fa402c684445b81f You're receiving 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 30 16:06:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 30 Apr 2020 12:06:32 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc/T18016 Message-ID: <5eaaf7881b682_61673f81cd4c695c81335a3@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/gc/T18016 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc/T18016 You're receiving 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 30 16:44:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 30 Apr 2020 12:44:08 -0400 Subject: [Git][ghc/ghc][wip/gc/T18016] nonmoving: Fix handling of dirty objects Message-ID: <5eab00583c630_61673f819b417d1c8153880@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/gc/T18016 at Glasgow Haskell Compiler / GHC Commits: 3bc91b7a by Ben Gamari at 2020-04-30T12:43:54-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 4 changed files: - rts/sm/NonMoving.c - rts/sm/NonMovingMark.c - rts/sm/NonMovingScav.c - rts/sm/Storage.c Changes: ===================================== rts/sm/NonMoving.c ===================================== @@ -228,6 +228,10 @@ Mutex concurrent_coll_finished_lock; * - Note [Static objects under the nonmoving collector] (Storage.c) describes * treatment of static objects. * + * - Note [Dirty flags in the non-moving collector] (NonMoving.c) describes + * how we use the DIRTY flags associated with MUT_VARs and TVARs to improve + * barrier efficiency. + * * * Note [Concurrent non-moving collection] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -369,6 +373,7 @@ Mutex concurrent_coll_finished_lock; * approximate due to concurrent collection and ultimately seems more costly * than the problem demands. * + * * Note [Spark management under the nonmoving collector] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Every GC, both minor and major, prunes the spark queue (using @@ -387,6 +392,88 @@ Mutex concurrent_coll_finished_lock; * BF_EVACUATED flag won't be set on the nursery blocks) and will consequently * only prune dead sparks living in the non-moving heap. * + * + * Note [Dirty flags in the non-moving collector] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Some mutable object types (e.g. MUT_VARs, TVARs) have a one-bit dirty flag + * encoded in their info table pointer. The moving collector uses this flag + * to minimize redundant mut_list entries. The flag is preserves the following + * simple invariant: + * + * An object being marked as dirty implies that the object is on mut_list. + * + * This allows a nice optimisation in the write barrier (e.g. dirty_MUT_VAR): + * if we write to an already-dirty object there is no need to + * push it to the mut_list as we know it's already there. + * + * During GC (scavenging) we will then keep track of whether all of the + * object's reference have been promoted. If so we can mark the object as clean. + * If not then we re-add it to mut_list and mark it as dirty. + * + * In the non-moving collector we use the same dirty flag to implement a + * related optimisation on the non-moving write barrier: Specifically, the + * snapshot invariant only requires that the non-moving write barrier applies + * to the *first* mutation to an object after collection begins. To achieve this, + * we impose the following invariant: + * + * An object being marked as dirty implies that all of its fields are on + * the mark queue (or, equivalently, update remembered set). + * + * With this guarantee we can safely make the the write barriers dirty objects + * no-ops. We perform this optimisation for the following object types: + * + * - MVAR + * - TVAR + * - MUT_VAR + * + * However, maintaining this invariant requires great care. For instance, + * consider the case of an MVar (which has two pointer fields) before + * preparatory collection: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ───────────╮ + * ┊ ╰────→ Y + * ┊ │ + * ┊ │ + * ╭───────────────────────╯ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * During the preparatory collection we promote Y to the nonmoving heap but + * fail to promote X. Since the failed_to_evac field is conservative (being set + * if *any* of the fields are not promoted), this gives us: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Y ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * This is bad. When we resume mutation a mutator may mutate MVAR A; since it's + * already dirty we would fail to add Y to the update remembered set, breaking the + * snapshot invariant and potentially losing track of the liveness of Z. + * + * To avoid this nonmovingScavengeOne we eagerly pushes the values of the + * fields of all objects which it fails to evacuate (e.g. MVAR A) to the update + * remembered set during the preparatory GC. This allows us to safely skip the + * non-moving write barrier without jeopardizing the snapshot invariant. + * */ memcount nonmoving_live_words = 0; ===================================== rts/sm/NonMovingMark.c ===================================== @@ -27,6 +27,7 @@ #include "sm/Storage.h" #include "CNF.h" +static bool check_in_nonmoving_heap(StgClosure *p); static void mark_closure (MarkQueue *queue, const StgClosure *p, StgClosure **origin); static void mark_tso (MarkQueue *queue, StgTSO *tso); static void mark_stack (MarkQueue *queue, StgStack *stack); @@ -450,10 +451,17 @@ push (MarkQueue *q, const MarkQueueEnt *ent) void markQueuePushClosureGC (MarkQueue *q, StgClosure *p) { + if (!check_in_nonmoving_heap(p)) { + return; + } + /* We should not make it here if we are doing a deadlock detect GC. * See Note [Deadlock detection under nonmoving collector]. + * This is actually no longer true due to call in nonmovingScavengeOne + * introduced due to Note [Dirty flags in the non-moving collector] + * (see NonMoving.c). */ - ASSERT(!deadlock_detect_gc); + //ASSERT(!deadlock_detect_gc); // Are we at the end of the block? if (q->top->head == MARK_QUEUE_BLOCK_ENTRIES) { ===================================== rts/sm/NonMovingScav.c ===================================== @@ -31,6 +31,11 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->head); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->tail); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->value); } else { mvar->header.info = &stg_MVAR_CLEAN_info; } @@ -46,6 +51,10 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->current_value); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->first_watch_queue_entry); } else { tvar->header.info = &stg_TVAR_CLEAN_info; } @@ -160,16 +169,21 @@ nonmovingScavengeOne (StgClosure *q) } case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: + case MUT_VAR_DIRTY: { + StgMutVar *mv = (StgMutVar *) p; gct->eager_promotion = false; - evacuate(&((StgMutVar *)p)->var); + evacuate(&mv->var); gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mv->var); } else { ((StgClosure *)q)->header.info = &stg_MUT_VAR_CLEAN_info; } break; + } case BLOCKING_QUEUE: { ===================================== rts/sm/Storage.c ===================================== @@ -1304,6 +1304,7 @@ dirty_MUT_VAR(StgRegTable *reg, StgMutVar *mvar, StgClosure *old) mvar->header.info = &stg_MUT_VAR_DIRTY_info; recordClosureMutated(cap, (StgClosure *) mvar); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure_(reg, old); } } @@ -1326,6 +1327,7 @@ dirty_TVAR(Capability *cap, StgTVar *p, p->header.info = &stg_TVAR_DIRTY_info; recordClosureMutated(cap,(StgClosure*)p); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure(cap, old); } } @@ -1407,6 +1409,7 @@ update_MVAR(StgRegTable *reg, StgClosure *p, StgClosure *old_val) { Capability *cap = regTableToCapability(reg); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c StgMVar *mvar = (StgMVar *) p; updateRemembSetPushClosure(cap, old_val); updateRemembSetPushClosure(cap, (StgClosure *) mvar->head); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bc91b7a9e33962b816ec81fd2155819c56d210f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bc91b7a9e33962b816ec81fd2155819c56d210f You're receiving 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 30 18:23:38 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 30 Apr 2020 14:23:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ww-max-worker-args-old-arity Message-ID: <5eab17aa28b6d_6167c5ce1b0817243@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ww-max-worker-args-old-arity You're receiving 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 30 19:04:44 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 15:04:44 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Mark rule args as non-tail-called Message-ID: <5eab214c39846_61673f819b417d1c818236@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 33e73c48 by Ben Gamari at 2020-04-30T15:04:28-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 99b962f4 by Ben Gamari at 2020-04-30T15:04:28-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 4e40c39e by Ben Gamari at 2020-04-30T15:04:28-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 34fe32df by Ömer Sinan Ağacan at 2020-04-30T15:04:35-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - 6e659dec by Ömer Sinan Ağacan at 2020-04-30T15:04:35-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 17 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Types/Basic.hs - hadrian/ghci-cabal - hadrian/ghci-stack - hadrian/hadrian.cabal - hadrian/hie-bios - hadrian/src/Rules.hs - + hadrian/src/Rules/ToolArgs.hs - rts/sm/GC.c - rts/sm/NonMoving.c - rts/sm/NonMovingSweep.c - + testsuite/tests/simplCore/should_compile/T18098.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -728,7 +728,7 @@ a right-hand side. In particular, we need to a) call 'markAllInsideLam' *unless* the binding is for a thunk, a one-shot lambda, or a non-recursive join point; and - b) call 'markAllNonTailCalled' *unless* the binding is for a join point. + b) call 'markAllNonTail' *unless* the binding is for a join point. Some examples, with how the free occurrences in e (assumed not to be a value lambda) get marked: @@ -1605,7 +1605,7 @@ occAnalUnfolding env mb_join_arity unf where env' = env `addInScope` bndrs (usage, args') = occAnalList env' args - final_usage = zapDetails (delDetailsList usage bndrs) + final_usage = markAllManyNonTail (delDetailsList usage bndrs) unf -> (emptyDetails, unf) @@ -1626,13 +1626,13 @@ occAnalRules env mb_join_arity bndr | otherwise = rule { ru_args = args', ru_rhs = rhs' } (lhs_uds, args') = occAnalList env' args - lhs_uds' = markAllMany $ + lhs_uds' = markAllManyNonTail $ lhs_uds `delDetailsList` bndrs (rhs_uds, rhs') = occAnal env' rhs -- Note [Rules are extra RHSs] -- Note [Rule dependency info] - rhs_uds' = markAllNonTailCalledIf (not exact_join) $ + rhs_uds' = markAllNonTailIf (not exact_join) $ markAllMany $ rhs_uds `delDetailsList` bndrs @@ -1758,7 +1758,7 @@ occAnal env (Tick tickish body) -- not the end of the world. | tickish `tickishScopesLike` SoftScope - = (markAllNonTailCalled usage, Tick tickish body') + = (markAllNonTail usage, Tick tickish body') | Breakpoint _ ids <- tickish = (usage_lam `andUDs` foldr addManyOcc emptyDetails ids, Tick tickish body') @@ -1769,7 +1769,7 @@ occAnal env (Tick tickish body) where !(usage,body') = occAnal env body -- for a non-soft tick scope, we can inline lambdas only - usage_lam = markAllNonTailCalled (markAllInsideLam usage) + usage_lam = markAllNonTail (markAllInsideLam usage) -- TODO There may be ways to make ticks and join points play -- nicer together, but right now there are problems: -- let j x = ... in tick (j 1) @@ -1780,13 +1780,13 @@ occAnal env (Tick tickish body) occAnal env (Cast expr co) = case occAnal env expr of { (usage, expr') -> - let usage1 = zapDetailsIf (isRhsEnv env) usage + let usage1 = markAllManyNonTailIf (isRhsEnv env) usage -- usage1: if we see let x = y `cast` co -- then mark y as 'Many' so that we don't -- immediately inline y again. usage2 = addManyOccs usage1 (coVarsOfCo co) -- usage2: see Note [Gather occurrences of coercion variables] - in (markAllNonTailCalled usage2, Cast expr' co) + in (markAllNonTail usage2, Cast expr' co) } occAnal env app@(App _ _) @@ -1799,7 +1799,7 @@ occAnal env app@(App _ _) occAnal env (Lam x body) | isTyVar x = case occAnal env body of { (body_usage, body') -> - (markAllNonTailCalled body_usage, Lam x body') + (markAllNonTail body_usage, Lam x body') } -- For value lambdas we do a special hack. Consider @@ -1815,7 +1815,7 @@ occAnal env expr@(Lam _ _) = case occAnalLamOrRhs env bndrs body of { (usage, tagged_bndrs, body') -> let expr' = mkLams tagged_bndrs body' - usage1 = markAllNonTailCalled usage + usage1 = markAllNonTail usage one_shot_gp = all isOneShotBndr tagged_bndrs final_usage = markAllInsideLamIf (not one_shot_gp) usage1 in @@ -1832,7 +1832,7 @@ occAnal env (Case scrut bndr ty alts) let alts_usage = foldr orUDs emptyDetails alts_usage_s (alts_usage1, tagged_bndr) = tagLamBinder alts_usage bndr - total_usage = markAllNonTailCalled scrut_usage `andUDs` alts_usage1 + total_usage = markAllNonTail scrut_usage `andUDs` alts_usage1 -- Alts can have tail calls, but the scrutinee can't in total_usage `seq` (total_usage, Case scrut' tagged_bndr ty alts') }} @@ -1893,7 +1893,7 @@ occAnalApp env (Var fun, args, ticks) all_uds = fun_uds `andUDs` final_args_uds !(args_uds, args') = occAnalArgs env args one_shots - !final_args_uds = markAllNonTailCalled $ + !final_args_uds = markAllNonTail $ markAllInsideLamIf (isRhsEnv env && is_exp) $ args_uds -- We mark the free vars of the argument of a constructor or PAP @@ -1923,7 +1923,7 @@ occAnalApp env (Var fun, args, ticks) -- See Note [Sources of one-shot information], bullet point A'] occAnalApp env (fun, args, ticks) - = (markAllNonTailCalled (fun_uds `andUDs` args_uds), + = (markAllNonTail (fun_uds `andUDs` args_uds), mkTicks ticks $ mkApps fun' args') where !(fun_uds, fun') = occAnal (addAppCtxt env args) fun @@ -2526,7 +2526,7 @@ data UsageDetails = UD { ud_env :: !OccInfoEnv , ud_z_many :: ZappedSet -- apply 'markMany' to these , ud_z_in_lam :: ZappedSet -- apply 'markInsideLam' to these - , ud_z_no_tail :: ZappedSet } -- apply 'markNonTailCalled' to these + , ud_z_no_tail :: ZappedSet } -- apply 'markNonTail' to these -- INVARIANT: All three zapped sets are subsets of the OccInfoEnv instance Outputable UsageDetails where @@ -2587,28 +2587,28 @@ emptyDetails = UD { ud_env = emptyVarEnv isEmptyDetails :: UsageDetails -> Bool isEmptyDetails = isEmptyVarEnv . ud_env -markAllMany, markAllInsideLam, markAllNonTailCalled, zapDetails +markAllMany, markAllInsideLam, markAllNonTail, markAllManyNonTail :: UsageDetails -> UsageDetails markAllMany ud = ud { ud_z_many = ud_env ud } markAllInsideLam ud = ud { ud_z_in_lam = ud_env ud } -markAllNonTailCalled ud = ud { ud_z_no_tail = ud_env ud } +markAllNonTail ud = ud { ud_z_no_tail = ud_env ud } -markAllInsideLamIf, markAllNonTailCalledIf :: Bool -> UsageDetails -> UsageDetails +markAllInsideLamIf, markAllNonTailIf :: Bool -> UsageDetails -> UsageDetails markAllInsideLamIf True ud = markAllInsideLam ud markAllInsideLamIf False ud = ud -markAllNonTailCalledIf True ud = markAllNonTailCalled ud -markAllNonTailCalledIf False ud = ud +markAllNonTailIf True ud = markAllNonTail ud +markAllNonTailIf False ud = ud -zapDetails = markAllMany . markAllNonTailCalled -- effectively sets to noOccInfo +markAllManyNonTail = markAllMany . markAllNonTail -- effectively sets to noOccInfo -zapDetailsIf :: Bool -- If this is true - -> UsageDetails -- Then do zapDetails on this +markAllManyNonTailIf :: Bool -- If this is true + -> UsageDetails -- Then do markAllManyNonTail on this -> UsageDetails -zapDetailsIf True uds = zapDetails uds -zapDetailsIf False uds = uds +markAllManyNonTailIf True uds = markAllManyNonTail uds +markAllManyNonTailIf False uds = uds lookupDetails :: UsageDetails -> Id -> OccInfo lookupDetails ud id @@ -2674,7 +2674,7 @@ doZappingByUnique (UD { ud_z_many = many occ1 | uniq `elemVarEnvByKey` many = markMany occ | uniq `elemVarEnvByKey` in_lam = markInsideLam occ | otherwise = occ - occ2 | uniq `elemVarEnvByKey` no_tail = markNonTailCalled occ1 + occ2 | uniq `elemVarEnvByKey` no_tail = markNonTail occ1 | otherwise = occ1 alterZappedSets :: UsageDetails -> (ZappedSet -> ZappedSet) -> UsageDetails @@ -2700,7 +2700,7 @@ adjustRhsUsage :: Maybe JoinArity -> RecFlag -> UsageDetails adjustRhsUsage mb_join_arity rec_flag bndrs usage = markAllInsideLamIf (not one_shot) $ - markAllNonTailCalledIf (not exact_join) $ + markAllNonTailIf (not exact_join) $ usage where one_shot = case mb_join_arity of @@ -2738,7 +2738,7 @@ tagLamBinder usage bndr = (usage2, bndr') where occ = lookupDetails usage bndr - bndr' = setBinderOcc (markNonTailCalled occ) bndr + bndr' = setBinderOcc (markNonTail occ) bndr -- Don't try to make an argument into a join point usage1 = usage `delDetails` bndr usage2 | isId bndr = addManyOccs usage1 (idUnfoldingVars bndr) @@ -2759,7 +2759,7 @@ tagNonRecBinder lvl usage binder will_be_join = decideJoinPointHood lvl usage [binder] occ' | will_be_join = -- must already be marked AlwaysTailCalled ASSERT(isAlwaysTailCalled occ) occ - | otherwise = markNonTailCalled occ + | otherwise = markNonTail occ binder' = setBinderOcc occ' binder usage' = usage `delDetails` binder in @@ -2930,7 +2930,7 @@ See Invariant 2a of Note [Invariants on join points] in GHC.Core ************************************************************************ -} -markMany, markInsideLam, markNonTailCalled :: OccInfo -> OccInfo +markMany, markInsideLam, markNonTail :: OccInfo -> OccInfo markMany IAmDead = IAmDead markMany occ = ManyOccs { occ_tail = occ_tail occ } @@ -2938,8 +2938,8 @@ markMany occ = ManyOccs { occ_tail = occ_tail occ } markInsideLam occ@(OneOcc {}) = occ { occ_in_lam = IsInsideLam } markInsideLam occ = occ -markNonTailCalled IAmDead = IAmDead -markNonTailCalled occ = occ { occ_tail = NoTailCallInfo } +markNonTail IAmDead = IAmDead +markNonTail occ = occ { occ_tail = NoTailCallInfo } addOccInfo, orOccInfo :: OccInfo -> OccInfo -> OccInfo ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -446,7 +446,7 @@ pprIdBndrInfo info lbv_info = oneShotInfo info has_prag = not (isDefaultInlinePragma prag_info) - has_occ = not (isManyOccs occ_info) + has_occ = not (isNoOccInfo occ_info) has_dmd = not $ isTopDmd dmd_info has_lbv = not (hasNoOneShotInfo lbv_info) ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -111,7 +111,7 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = (_, _, fv_details) = mkVirtHeapOffsets dflags header [] -- Don't drop the non-void args until the closure info has been made ; forkClosureBody (closureCodeBody True id closure_info ccs - (nonVoidIds args) (length args) body fv_details) + args body fv_details) ; return () } @@ -358,8 +358,8 @@ mkRhsClosure dflags bndr cc fvs upd_flag args body -- forkClosureBody: (a) ensure that bindings in here are not seen elsewhere -- (b) ignore Sequel from context; use empty Sequel -- And compile the body - closureCodeBody False bndr closure_info cc (nonVoidIds args) - (length args) body fv_details + closureCodeBody False bndr closure_info cc args + body fv_details -- BUILD THE OBJECT -- ; (use_cc, blame_cc) <- chooseDynCostCentres cc args body @@ -436,8 +436,7 @@ closureCodeBody :: Bool -- whether this is a top-level binding -> Id -- the closure's name -> ClosureInfo -- Lots of information about this closure -> CostCentreStack -- Optional cost centre attached to closure - -> [NonVoid Id] -- incoming args to the closure - -> Int -- arity, including void args + -> [Id] -- incoming args to the closure -> CgStgExpr -> [(NonVoid Id, ByteOff)] -- the closure's free vars -> FCode () @@ -452,31 +451,32 @@ closureCodeBody :: Bool -- whether this is a top-level binding normal form, so there is no need to set up an update frame. -} -closureCodeBody top_lvl bndr cl_info cc _args arity body fv_details - | arity == 0 -- No args i.e. thunk +-- No args i.e. thunk +closureCodeBody top_lvl bndr cl_info cc [] body fv_details = withNewTickyCounterThunk (isStaticClosure cl_info) (closureUpdReqd cl_info) (closureName cl_info) $ emitClosureProcAndInfoTable top_lvl bndr lf_info info_tbl [] $ - \(_, node, _) -> thunkCode cl_info fv_details cc node arity body + \(_, node, _) -> thunkCode cl_info fv_details cc node body where lf_info = closureLFInfo cl_info info_tbl = mkCmmInfo cl_info bndr cc -closureCodeBody top_lvl bndr cl_info cc args arity body fv_details - = -- Note: args may be [], if all args are Void - withNewTickyCounterFun - (closureSingleEntry cl_info) - (closureName cl_info) - args $ do { +closureCodeBody top_lvl bndr cl_info cc args@(arg0:_) body fv_details + = let nv_args = nonVoidIds args + arity = length args + in + -- See Note [OneShotInfo overview] in GHC.Types.Basic. + withNewTickyCounterFun (isOneShotBndr arg0) (closureName cl_info) + nv_args $ do { ; let lf_info = closureLFInfo cl_info info_tbl = mkCmmInfo cl_info bndr cc -- Emit the main entry code - ; emitClosureProcAndInfoTable top_lvl bndr lf_info info_tbl args $ + ; emitClosureProcAndInfoTable top_lvl bndr lf_info info_tbl nv_args $ \(_offset, node, arg_regs) -> do -- Emit slow-entry code (for entering a closure through a PAP) { mkSlowEntryCode bndr cl_info arg_regs @@ -565,15 +565,15 @@ mkSlowEntryCode bndr cl_info arg_regs -- function closure is already in `Node' ----------------------------------------- thunkCode :: ClosureInfo -> [(NonVoid Id, ByteOff)] -> CostCentreStack - -> LocalReg -> Int -> CgStgExpr -> FCode () -thunkCode cl_info fv_details _cc node arity body + -> LocalReg -> CgStgExpr -> FCode () +thunkCode cl_info fv_details _cc node body = do { dflags <- getDynFlags ; let node_points = nodeMustPointToIt dflags (closureLFInfo cl_info) node' = if node_points then Just node else Nothing ; ldvEnterClosure cl_info (CmmLocal node) -- NB: Node always points when profiling -- Heap overflow check - ; entryHeapCheck cl_info node' arity [] $ do + ; entryHeapCheck cl_info node' 0 [] $ do { -- Overwrite with black hole if necessary -- but *after* the heap-overflow check ; tickyEnterThunk cl_info ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -48,7 +48,7 @@ module GHC.StgToCmm.Closure ( -- ** Predicates -- These are really just functions on LambdaFormInfo - closureUpdReqd, closureSingleEntry, + closureUpdReqd, closureReEntrant, closureFunInfo, isToplevClosure, @@ -201,7 +201,6 @@ argPrimRep arg = typePrimRep1 (stgArgType arg) data LambdaFormInfo = LFReEntrant -- Reentrant closure (a function) TopLevelFlag -- True if top level - OneShotInfo !RepArity -- Arity. Invariant: always > 0 !Bool -- True <=> no fvs ArgDescr -- Argument descriptor (should really be in ClosureInfo) @@ -285,8 +284,7 @@ mkLFReEntrant :: TopLevelFlag -- True of top level mkLFReEntrant _ _ [] _ = pprPanic "mkLFReEntrant" empty mkLFReEntrant top fvs args arg_descr - = LFReEntrant top os_info (length args) (null fvs) arg_descr - where os_info = idOneShotInfo (head args) + = LFReEntrant top (length args) (null fvs) arg_descr ------------- mkLFThunk :: Type -> TopLevelFlag -> [Id] -> UpdateFlag -> LambdaFormInfo @@ -335,7 +333,7 @@ mkLFImported id -- the id really does point directly to the constructor | arity > 0 - = LFReEntrant TopLevel noOneShotInfo arity True (panic "arg_descr") + = LFReEntrant TopLevel arity True (panic "arg_descr") | otherwise = mkLFArgument id -- Not sure of exact arity @@ -384,9 +382,9 @@ tagForArity dflags arity lfDynTag :: DynFlags -> LambdaFormInfo -> DynTag -- Return the tag in the low order bits of a variable bound -- to this LambdaForm -lfDynTag dflags (LFCon con) = tagForCon dflags con -lfDynTag dflags (LFReEntrant _ _ arity _ _) = tagForArity dflags arity -lfDynTag _ _other = 0 +lfDynTag dflags (LFCon con) = tagForCon dflags con +lfDynTag dflags (LFReEntrant _ arity _ _) = tagForArity dflags arity +lfDynTag _ _other = 0 ----------------------------------------------------------------------------- @@ -407,11 +405,11 @@ isLFReEntrant _ = False ----------------------------------------------------------------------------- lfClosureType :: LambdaFormInfo -> ClosureTypeInfo -lfClosureType (LFReEntrant _ _ arity _ argd) = Fun arity argd -lfClosureType (LFCon con) = Constr (dataConTagZ con) - (dataConIdentity con) -lfClosureType (LFThunk _ _ _ is_sel _) = thunkClosureType is_sel -lfClosureType _ = panic "lfClosureType" +lfClosureType (LFReEntrant _ arity _ argd) = Fun arity argd +lfClosureType (LFCon con) = Constr (dataConTagZ con) + (dataConIdentity con) +lfClosureType (LFThunk _ _ _ is_sel _) = thunkClosureType is_sel +lfClosureType _ = panic "lfClosureType" thunkClosureType :: StandardFormInfo -> ClosureTypeInfo thunkClosureType (SelectorThunk off) = ThunkSelector off @@ -431,7 +429,7 @@ nodeMustPointToIt :: DynFlags -> LambdaFormInfo -> Bool -- this closure has R1 (the "Node" register) pointing to the -- closure itself --- the "self" argument -nodeMustPointToIt _ (LFReEntrant top _ _ no_fvs _) +nodeMustPointToIt _ (LFReEntrant top _ no_fvs _) = not no_fvs -- Certainly if it has fvs we need to point to it || isNotTopLevel top -- See Note [GC recovery] -- For lex_profiling we also access the cost centre for a @@ -566,7 +564,7 @@ getCallMethod dflags _ id _ n_args v_args _cg_loc -- self-recursive tail calls] in GHC.StgToCmm.Expr for more details = JumpToIt block_id args -getCallMethod dflags name id (LFReEntrant _ _ arity _ _) n_args _v_args _cg_loc +getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _v_args _cg_loc _self_loop_info | n_args == 0 -- No args at all && not (gopt Opt_SccProfilingOn dflags) @@ -811,11 +809,6 @@ lfUpdatable :: LambdaFormInfo -> Bool lfUpdatable (LFThunk _ _ upd _ _) = upd lfUpdatable _ = False -closureSingleEntry :: ClosureInfo -> Bool -closureSingleEntry (ClosureInfo { closureLFInfo = LFThunk _ _ upd _ _}) = not upd -closureSingleEntry (ClosureInfo { closureLFInfo = LFReEntrant _ OneShotLam _ _ _}) = True -closureSingleEntry _ = False - closureReEntrant :: ClosureInfo -> Bool closureReEntrant (ClosureInfo { closureLFInfo = LFReEntrant {} }) = True closureReEntrant _ = False @@ -824,8 +817,8 @@ closureFunInfo :: ClosureInfo -> Maybe (RepArity, ArgDescr) closureFunInfo (ClosureInfo { closureLFInfo = lf_info }) = lfFunInfo lf_info lfFunInfo :: LambdaFormInfo -> Maybe (RepArity, ArgDescr) -lfFunInfo (LFReEntrant _ _ arity _ arg_desc) = Just (arity, arg_desc) -lfFunInfo _ = Nothing +lfFunInfo (LFReEntrant _ arity _ arg_desc) = Just (arity, arg_desc) +lfFunInfo _ = Nothing funTag :: DynFlags -> ClosureInfo -> DynTag funTag dflags (ClosureInfo { closureLFInfo = lf_info }) @@ -834,9 +827,9 @@ funTag dflags (ClosureInfo { closureLFInfo = lf_info }) isToplevClosure :: ClosureInfo -> Bool isToplevClosure (ClosureInfo { closureLFInfo = lf_info }) = case lf_info of - LFReEntrant TopLevel _ _ _ _ -> True - LFThunk TopLevel _ _ _ _ -> True - _other -> False + LFReEntrant TopLevel _ _ _ -> True + LFThunk TopLevel _ _ _ _ -> True + _other -> False -------------------------------------- -- Label generation ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -82,27 +82,22 @@ module GHC.StgToCmm.Ticky ( tickyHeapCheck, tickyStackCheck, - tickyUnknownCall, tickyDirectCall, + tickyDirectCall, tickyPushUpdateFrame, tickyUpdateFrameOmitted, tickyEnterDynCon, - tickyEnterStaticCon, - tickyEnterViaNode, tickyEnterFun, - tickyEnterThunk, tickyEnterStdThunk, -- dynamic non-value - -- thunks only + tickyEnterThunk, tickyEnterLNE, tickyUpdateBhCaf, - tickyBlackHole, tickyUnboxedTupleReturn, tickyReturnOldCon, tickyReturnNewCon, - tickyKnownCallTooFewArgs, tickyKnownCallExact, tickyKnownCallExtraArgs, - tickySlowCall, tickySlowCallPat, + tickySlowCall ) where import GHC.Prelude @@ -276,10 +271,8 @@ tickyUpdateFrameOmitted = ifTicky $ bumpTickyCounter (fsLit "UPDF_OMITTED_ctr") -- bump of name-specific ticky counter into. On the other hand, we can -- still track allocation their allocation. -tickyEnterDynCon, tickyEnterStaticCon, tickyEnterViaNode :: FCode () -tickyEnterDynCon = ifTicky $ bumpTickyCounter (fsLit "ENT_DYN_CON_ctr") -tickyEnterStaticCon = ifTicky $ bumpTickyCounter (fsLit "ENT_STATIC_CON_ctr") -tickyEnterViaNode = ifTicky $ bumpTickyCounter (fsLit "ENT_VIA_NODE_ctr") +tickyEnterDynCon :: FCode () +tickyEnterDynCon = ifTicky $ bumpTickyCounter (fsLit "ENT_DYN_CON_ctr") tickyEnterThunk :: ClosureInfo -> FCode () tickyEnterThunk cl_info @@ -291,7 +284,7 @@ tickyEnterThunk cl_info registerTickyCtrAtEntryDyn ticky_ctr_lbl bumpTickyEntryCount ticky_ctr_lbl } where - updatable = closureSingleEntry cl_info + updatable = not (closureUpdReqd cl_info) static = isStaticClosure cl_info ctr | static = if updatable then fsLit "ENT_STATIC_THK_SINGLE_ctr" @@ -299,16 +292,6 @@ tickyEnterThunk cl_info | otherwise = if updatable then fsLit "ENT_DYN_THK_SINGLE_ctr" else fsLit "ENT_DYN_THK_MANY_ctr" -tickyEnterStdThunk :: ClosureInfo -> FCode () -tickyEnterStdThunk = tickyEnterThunk - -tickyBlackHole :: Bool{-updatable-} -> FCode () -tickyBlackHole updatable - = ifTicky (bumpTickyCounter ctr) - where - ctr | updatable = (fsLit "UPD_BH_SINGLE_ENTRY_ctr") - | otherwise = (fsLit "UPD_BH_UPDATABLE_ctr") - tickyUpdateBhCaf :: ClosureInfo -> FCode () tickyUpdateBhCaf cl_info = ifTicky (bumpTickyCounter ctr) ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -67,7 +67,7 @@ module GHC.Types.Basic ( OccInfo(..), noOccInfo, seqOccInfo, zapFragileOcc, isOneOcc, isDeadOcc, isStrongLoopBreaker, isWeakLoopBreaker, isManyOccs, - strongLoopBreaker, weakLoopBreaker, + isNoOccInfo, strongLoopBreaker, weakLoopBreaker, InsideLam(..), OneBranch(..), @@ -243,13 +243,80 @@ instance Outputable Alignment where ************************************************************************ -} +{- +Note [OneShotInfo overview] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Lambda-bound Ids (and only lambda-bound Ids) may be decorated with +one-shot info. The idea is that if we see + (\x{one-shot}. e) +it means that this lambda will only be applied once. In particular +that means we can float redexes under the lambda without losing +work. For example, consider + let t = expensive in + (\x{one-shot}. case t of { True -> ...; False -> ... }) + +Because it's a one-shot lambda, we can safely inline t, giving + (\x{one_shot}. case of of + { True -> ...; False -> ... }) + +Moving parts: + +* Usage analysis, performed as part of demand-analysis, finds + out whether functions call their argument once. Consider + f g x = Just (case g x of { ... }) + + Here 'f' is lazy in 'g', but it guarantees to call it no + more than once. So g will get a C1(U) usage demand. + +* Occurrence analysis propagates this usage information + (in the demand signature of a function) to its calls. + Example, given 'f' above + f (\x.e) blah + + Since f's demand signature says it has a C1(U) usage demand on its + first argument, the occurrence analyser sets the \x to be one-shot. + This is done via the occ_one_shots field of OccEnv. + +* Float-in and float-out take account of one-shot-ness + +* Occurrence analysis doesn't set "inside-lam" for occurrences inside + a one-shot lambda + +Other notes + +* A one-shot lambda can use its argument many times. To elaborate + the example above + let t = expensive in + (\x{one-shot}. case t of { True -> x+x; False -> x*x }) + + Here the '\x' is one-shot, which justifies inlining 't', + but x is used many times. That's absolutely fine. + +* It's entirely possible to have + (\x{one-shot}. \y{many-shot}. e) + + For example + let t = expensive + g = \x -> let v = x+t in + \y -> x + v + in map (g 5) xs + + Here the `\x` is a one-shot binder: `g` is applied to one argument + exactly once. And because the `\x` is one-shot, it would be fine to + float that `let t = expensive` binding inside the `\x`. + + But the `\y` is most definitely not one-shot! +-} + -- | If the 'Id' is a lambda-bound variable then it may have lambda-bound -- variable info. Sometimes we know whether the lambda binding this variable --- is a \"one-shot\" lambda; that is, whether it is applied at most once. +-- is a "one-shot" lambda; that is, whether it is applied at most once. -- -- This information may be useful in optimisation, as computations may -- safely be floated inside such a lambda without risk of duplicating -- work. +-- +-- See also Note [OneShotInfo overview] above. data OneShotInfo = NoOneShotInfo -- ^ No information | OneShotLam -- ^ The lambda is applied at most once. @@ -958,6 +1025,10 @@ See OccurAnal Note [Weak loop breakers] noOccInfo :: OccInfo noOccInfo = ManyOccs { occ_tail = NoTailCallInfo } +isNoOccInfo :: OccInfo -> Bool +isNoOccInfo ManyOccs { occ_tail = NoTailCallInfo } = True +isNoOccInfo _ = False + isManyOccs :: OccInfo -> Bool isManyOccs ManyOccs{} = True isManyOccs _ = False ===================================== hadrian/ghci-cabal ===================================== @@ -3,5 +3,5 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. -GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" -ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-cabal" tool:ghc/Main.hs -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" +ghci $GHC_FLAGS $@ -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m ===================================== hadrian/ghci-stack ===================================== @@ -4,4 +4,4 @@ set -e # Replace newlines with spaces, as these otherwise break the ghci invocation on windows. GHC_FLAGS="$GHC_FLAGS $(TERM=dumb CABFLAGS=-v0 "hadrian/build-stack" tool-args -q --build-root=.hadrian_ghci --flavour=ghc-in-ghci $HADRIAN_ARGS | tr '\n\r' ' ')" -stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 ghc/Main.hs +RTS -A128m +stack exec -- ghci $GHC_FLAGS "$@" -fno-code -fwrite-interface -hidir=.hadrian_ghci/interface -O0 +RTS -A128m ===================================== hadrian/hadrian.cabal ===================================== @@ -77,6 +77,7 @@ executable hadrian , Rules.Program , Rules.Register , Rules.Rts + , Rules.ToolArgs , Rules.Selftest , Rules.SimpleTargets , Rules.SourceDist ===================================== hadrian/hie-bios ===================================== @@ -3,7 +3,5 @@ # When run, this program will output a list of arguments which are necessary to # load the GHC library component into GHCi. The program is used by `ghcide` in # order to automatically set up the correct GHC API session for a project. -TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool-args -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT -echo -ighc >> $HIE_BIOS_OUTPUT -echo "ghc/Main.hs" >> $HIE_BIOS_OUTPUT +TERM=dumb CABFLAGS=-v0 $PWD/hadrian/build-cabal tool:$1 -q --build-root=.hie-bios --flavour=ghc-in-ghci > $HIE_BIOS_OUTPUT ===================================== hadrian/src/Rules.hs ===================================== @@ -24,43 +24,12 @@ import qualified Rules.Program import qualified Rules.Register import qualified Rules.Rts import qualified Rules.SimpleTargets +import Rules.ToolArgs import Settings import Settings.Program (programContext) import Target import UserSettings --- | @tool-args@ is used by tooling in order to get the arguments necessary --- to set up a GHC API session which can compile modules from GHC. When --- run, the target prints out the arguments that would be passed to @ghc@ --- during normal compilation to @stdout at . --- --- This target is called by the `ghci` script in order to load all of GHC's --- modules into GHCi. -toolArgsTarget :: Rules () -toolArgsTarget = do - "tool-args" ~> do - -- We can't build DLLs on Windows (yet). Actually we should only - -- include the dynamic way when we have a dynamic host GHC, but just - -- checking for Windows seems simpler for now. - let fake_target = target (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) - (Ghc ToolArgs Stage0) [] ["ignored"] - - -- need the autogenerated files so that they are precompiled - includesDependencies Stage0 >>= need - interpret fake_target Rules.Generate.compilerDependencies >>= need - - root <- buildRoot - let dir = buildDir (vanillaContext Stage0 compiler) - need [ root -/- dir -/- "Config.hs" ] - need [ root -/- dir -/- "GHC" -/- "Parser.hs" ] - need [ root -/- dir -/- "GHC" -/- "Parser" -/- "Lexer.hs" ] - need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Parser.hs" ] - need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Lexer.hs" ] - - -- Find out the arguments that are needed to load a module into the - -- session - arg_list <- interpret fake_target getArgs - liftIO $ putStrLn (intercalate "\n" arg_list) allStages :: [Stage] allStages = [minBound .. maxBound] ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -0,0 +1,128 @@ +module Rules.ToolArgs(toolArgsTarget) where + +import qualified Rules.Generate +import Development.Shake +import Target +import Context +import Stage +import Expression + +import Packages +import Settings +import Hadrian.Oracles.Cabal +import Hadrian.Haskell.Cabal.Type +import System.Directory (canonicalizePath) + +-- | @tool:@ is used by tooling in order to get the arguments necessary +-- to set up a GHC API session which can compile modules from GHC. When +-- run, the target prints out the arguments that would be passed to @ghc@ +-- during normal compilation to @stdout@ for the file passed as an +-- argument. +-- +-- This target is called by the `ghci.sh` script in order to load all of GHC's +-- modules into GHCi. It is invoked with argument `tool:ghc/Main.hs` in +-- that script so that we can load the whole library and executable +-- components into GHCi. +-- +-- In the future where we have multi-component ghci this code can be +-- modified to supply the right arguments for that. At the moment it is +-- also used for GHC's support for multi-component ghcide (see the +-- `hadrian/hie-bios` script). + + +-- | A phony target of form `tool:path/to/file.hs` which returns the +-- options needed to compile the specific file. +toolArgsTarget :: Rules () +toolArgsTarget = do + phonys (\s -> if "tool:" `isPrefixOf` s then Just (toolRuleBody (drop 5 s)) else Nothing) + +toolRuleBody :: FilePath -> Action () +toolRuleBody fp = do + mm <- dirMap + cfp <- liftIO $ canonicalizePath fp + case find (flip isPrefixOf cfp . fst) mm of + Just (_, (p, extra)) -> mkToolTarget extra p + Nothing -> fail $ "No prefixes matched " ++ show fp ++ " IN\n " ++ show mm + +mkToolTarget :: [String] -> Package -> Action () +mkToolTarget es p = do + -- This builds automatically generated dependencies. Not sure how to do + -- this generically yet. + allDeps + let fake_target = target (Context Stage0 p (if windowsHost then vanilla else dynamic)) + (Ghc ToolArgs Stage0) [] ["ignored"] + arg_list <- interpret fake_target getArgs + liftIO $ putStrLn (intercalate "\n" (arg_list ++ es)) +allDeps :: Action () +allDeps = do + do + -- We can't build DLLs on Windows (yet). Actually we should only + -- include the dynamic way when we have a dynamic host GHC, but just + -- checking for Windows seems simpler for now. + let fake_target = target (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) + (Ghc ToolArgs Stage0) [] ["ignored"] + + -- need the autogenerated files so that they are precompiled + includesDependencies Stage0 >>= need + interpret fake_target Rules.Generate.compilerDependencies >>= need + + root <- buildRoot + let dir = buildDir (vanillaContext Stage0 compiler) + need [ root -/- dir -/- "Config.hs" ] + need [ root -/- dir -/- "GHC" -/- "Parser.hs" ] + need [ root -/- dir -/- "GHC" -/- "Parser" -/- "Lexer.hs" ] + need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Parser.hs" ] + need [ root -/- dir -/- "GHC" -/- "Cmm" -/- "Lexer.hs" ] + +-- This list is quite a lot like stage0packages but doesn't include +-- critically the `exe:ghc` component as that depends on the GHC library +-- which takes a while to compile. +toolTargets :: [Package] +toolTargets = [ array + , bytestring + , templateHaskell + , containers + , deepseq + , directory + , exceptions + , filepath + , compiler + , ghcCompact + , ghcPrim + --, haskeline + , hp2ps + , hsc2hs + , pretty + , process + , rts + , stm + , time + , unlit + , xhtml ] + +-- | Create a mapping from files to which component it belongs to. +dirMap :: Action [(FilePath, (Package, [String]))] +dirMap = do + auto <- concatMapM go toolTargets + -- Mush the ghc executable into the compiler component so the whole of ghc is not built when + -- configuring + ghc_exe <- mkGhc + return (auto ++ [ghc_exe]) + + where + -- Make a separate target for the exe:ghc target because otherwise + -- configuring would build the whole GHC library which we probably + -- don't want to do. + mkGhc = do + let c = (Context Stage0 compiler (if windowsHost then vanilla else dynamic)) + cd <- readContextData c + fp <- liftIO $ canonicalizePath "ghc/" + return (fp, (compiler, "-ighc" : modules cd ++ otherModules cd ++ ["ghc/Main.hs"])) + go p = do + let c = (Context Stage0 p (if windowsHost then vanilla else dynamic)) + -- readContextData has the effect of configuring the package so all + -- dependent packages will also be built. + cd <- readContextData c + ids <- liftIO $ mapM canonicalizePath [pkgPath p i | i <- srcDirs cd] + return $ map (,(p, modules cd ++ otherModules cd)) ids + ===================================== rts/sm/GC.c ===================================== @@ -738,11 +738,13 @@ GarbageCollect (uint32_t collect_gen, } } // for all generations - // Flush the update remembered set. See Note [Eager update remembered set + // Flush the update remembered sets. See Note [Eager update remembered set // flushing] in NonMovingMark.c if (RtsFlags.GcFlags.useNonmoving) { RELEASE_SM_LOCK; - nonmovingAddUpdRemSetBlocks(&gct->cap->upd_rem_set.queue); + for (n = 0; n < n_capabilities; n++) { + nonmovingAddUpdRemSetBlocks(&capabilities[n]->upd_rem_set.queue); + } ACQUIRE_SM_LOCK; } ===================================== rts/sm/NonMoving.c ===================================== @@ -402,10 +402,10 @@ static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block seg->link = NULL; seg->todo_link = NULL; seg->next_free = 0; - nonmovingClearBitmap(seg); bd->nonmoving_segment.log_block_size = log_block_size; bd->nonmoving_segment.next_free_snap = 0; bd->u.scan = nonmovingSegmentGetBlock(seg, 0); + nonmovingClearBitmap(seg); } // Add a segment to the free list. ===================================== rts/sm/NonMovingSweep.c ===================================== @@ -31,12 +31,11 @@ enum SweepResult { GNUC_ATTR_HOT static enum SweepResult nonmovingSweepSegment(struct NonmovingSegment *seg) { + const nonmoving_block_idx blk_cnt = nonmovingSegmentBlockCount(seg); bool found_free = false; bool found_live = false; - for (nonmoving_block_idx i = 0; - i < nonmovingSegmentBlockCount(seg); - ++i) + for (nonmoving_block_idx i = 0; i < blk_cnt; ++i) { if (seg->bitmap[i] == nonmovingMarkEpoch) { found_live = true; ===================================== testsuite/tests/simplCore/should_compile/T18098.hs ===================================== @@ -0,0 +1,78 @@ +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE KindSignatures #-} +module Bug where + +import Control.Monad.ST (runST, ST) +import Data.Kind (Type) +import Data.Functor.Identity (Identity(..)) + +gcons :: (GVector v a) => a -> Stream Identity (Chunk v a) -> v a +gcons x tb = gmvmunstreamUnknown $ sappend (ssingleton x) tb +{-# INLINE gcons #-} + +data Chunk v a = MkChunk (forall s. GVector v a => Mutable v s a -> ST s ()) + +data Step s a = Yield a s | Done + +data Stream m a = forall s. Stream (s -> m (Step s a)) s + +data Mutable :: (Type -> Type) -> Type -> Type -> Type + +class GVector v a where + gmbasicLength :: Mutable v s a -> Int + gmbasicUnsafeSlice :: Mutable v s a -> Mutable v s a + gmbasicUnsafeNew :: ST s (Mutable v s a) + gmbasicUnsafeWrite :: a -> Mutable v s a -> ST s () + gmbasicUnsafeGrow :: Mutable v s a -> Int -> m (Mutable v s a) + gbasicUnsafeFreeze :: Mutable v s a -> ST s (v a) + +sfoldlM :: (a -> b -> ST s a) -> (t -> Step t b) -> a -> t -> ST s a +sfoldlM m step = foldlM_loop + where + foldlM_loop z s + = case step s of + Yield x s' -> do { z' <- m z x; foldlM_loop z' s' } + Done -> return z +{-# INLINE [1] sfoldlM #-} + +sappend :: Stream Identity a -> Stream Identity a -> Stream Identity a +Stream stepa ta `sappend` Stream stepb _ = Stream step (Left ta) + where + {-# INLINE [0] step #-} + step (Left sa) = do + r <- stepa sa + return $ case r of + Yield x _ -> Yield x (Left sa) + Done -> Done + step (Right sb) = do + r <- stepb sb + return $ case r of + Yield x _ -> Yield x (Right sb) + Done -> Done +{-# INLINE [1] sappend #-} + +ssingleton :: Monad m => a -> Stream m (Chunk v a) +ssingleton x = Stream (return . step) True + where + {-# INLINE [0] step #-} + step True = Yield (MkChunk (gmbasicUnsafeWrite x)) False + step False = Done +{-# INLINE [1] ssingleton #-} + +gmvmunstreamUnknown :: GVector v a => Stream Identity (Chunk v a) -> v a +gmvmunstreamUnknown (Stream vstep u) + = runST (do + v <- gmbasicUnsafeNew + sfoldlM copyChunk (runIdentity . vstep) (v,0) u + gbasicUnsafeFreeze v) + where + {-# INLINE [0] copyChunk #-} + copyChunk (v,i) (MkChunk f) + = do + v' <- gmbasicUnsafeGrow v (gmbasicLength v) + f (gmbasicUnsafeSlice v') + return (v',i) +{-# INLINE gmvmunstreamUnknown #-} ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -317,3 +317,4 @@ test('T17966', # NB: T17810: -fspecialise-aggressively test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) +test('T18098', normal, compile, ['-dcore-lint -O2']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d8b44dad5d0d417c86a2d65f14e53986fd499183...6e659dece9614de57f99e0322dad399491b620bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d8b44dad5d0d417c86a2d65f14e53986fd499183...6e659dece9614de57f99e0322dad399491b620bc You're receiving 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 30 19:16:18 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Thu, 30 Apr 2020 15:16:18 -0400 Subject: [Git][ghc/ghc][wip/keep-going-hs-boot] 475 commits: Improve/fix -fcatch-bottoms documentation Message-ID: <5eab24023b422_6167c5ce1b0818844a@gitlab.haskell.org.mail> John Ericson pushed to branch wip/keep-going-hs-boot at Glasgow Haskell Compiler / GHC Commits: 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 052f7593 by John Ericson at 2020-04-30T14:28:23-04:00 Clean up boot vs non-boot disambiguating types We often have (ModuleName, Bool) or (Module, Bool) pairs for "extended" module names (without or with a unit id) disambiguating boot and normal modules. We think this is important enough across the compiler that it deserves a new nominal product type. We do this with synnoyms and a functor named with a `Gen` prefix, matching other newly created definitions. It was also requested that we keep custom `IsBoot` / `NotBoot` sum type. So we have it too. This means changing many the many bools to use that instead. - - - - - b34931e4 by John Ericson at 2020-04-30T15:10:50-04:00 Switch from HscSource to IsBootInterface for module lookup in GhcMake We look up modules by their name, and not their contents. There is no way to separately reference a signature vs regular module; you get what you get. Only boot files can be referenced indepenently with `import {-# SOURCE #-}`. - - - - - 06e42de1 by John Ericson at 2020-04-30T15:10:50-04:00 For -fkeep-failed do not duplicate dependency edge code We now compute the deps for -fkeep-failed the same way that the original graph calculates them, so the edges are correct. Upsweep really ought to take the graph rather than a topological sort so we are never recalculating anything, but at least things are done consistently now. - - - - - 15 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/win32-init.sh - CODEOWNERS - HACKING.md - aclocal.m4 - boot - + compiler/GHC.hs - + compiler/GHC/Builtin/Names.hs - + compiler/GHC/Builtin/Names.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f6bbd10e2e0f8e37e5a713d94f360a2722aeab1...06e42de162b5679c1737dc2c8962526d401c627f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f6bbd10e2e0f8e37e5a713d94f360a2722aeab1...06e42de162b5679c1737dc2c8962526d401c627f You're receiving 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 30 19:29:01 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 30 Apr 2020 15:29:01 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5eab26fd1feab_61673f81cd4c695c81903c0@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 258e8031 by Sebastian Graf at 2020-04-30T21:28:53+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 5 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1997,7 +1997,7 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Remove ones that have too many worker variables small_pats = filterOut too_big non_dups - too_big (vars,_) = not (isWorkerSmallEnough (sc_dflags env) vars) + too_big (vars,args) = not (isWorkerSmallEnough (sc_dflags env) (length args) vars) -- We are about to construct w/w pair in 'spec_one'. -- Omit specialisation leading to high arity workers. -- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -162,7 +162,7 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if isWorkerSmallEnough dflags work_args + ; if isWorkerSmallEnough dflags (length demands) work_args && not (too_many_args_for_join_point wrap_args) && ((useful1 && not only_one_void_argument) || useful2) then return (Just (worker_args_dmds, length work_call_args, @@ -203,10 +203,13 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info = False -- See Note [Limit w/w arity] -isWorkerSmallEnough :: DynFlags -> [Var] -> Bool -isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags +isWorkerSmallEnough :: DynFlags -> Int -> [Var] -> Bool +isWorkerSmallEnough dflags old_n_args vars + = count isId vars <= max old_n_args (maxWorkerArgs dflags) -- We count only Free variables (isId) to skip Type, Kind -- variables which have no runtime representation. + -- Also if the function took 82 arguments before (old_n_args), it's fine if + -- it takes <= 82 arguments afterwards. {- Note [Always do CPR w/w] @@ -227,7 +230,8 @@ Guard against high worker arity as it generates a lot of stack traffic. A simplified example is #11565#comment:6 Current strategy is very simple: don't perform w/w transformation at all -if the result produces a wrapper with arity higher than -fmax-worker-args=. +if the result produces a wrapper with arity higher than -fmax-worker-args +and the number arguments before w/w. It is a bit all or nothing, consider ===================================== testsuite/tests/stranal/should_compile/T18122.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -fforce-recomp -O2 -fmax-worker-args=1 #-} +module Lib where + +foo :: (Int, Int) -> Int -> Int +foo (x, y) z = x+z +{-# NOINLINE foo #-} ===================================== testsuite/tests/stranal/should_compile/T18122.stderr ===================================== @@ -0,0 +1,83 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 35, types: 27, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule3 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule3 = GHC.Types.TrNameS Lib.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule2 = "Lib"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule1 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule1 = GHC.Types.TrNameS Lib.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule :: GHC.Types.Module +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +Lib.$trModule = GHC.Types.Module Lib.$trModule3 Lib.$trModule1 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$wfoo [InlPrag=NOINLINE] + :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=2, Str=, Unf=OtherCon []] +Lib.$wfoo = (GHC.Prim.+#) + +-- RHS size: {terms: 18, types: 14, coercions: 0, joins: 0/0} +foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int +[GblId, + Arity=2, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (w_sGZ [Occ=Once!] :: (Int, Int)) + (w1_sH0 [Occ=Once!] :: Int) -> + case w_sGZ of { (ww1_sH3 [Occ=Once!], _ [Occ=Dead]) -> + case ww1_sH3 of { GHC.Types.I# ww4_sH6 [Occ=Once] -> + case w1_sH0 of { GHC.Types.I# ww6_sHc [Occ=Once] -> + case Lib.$wfoo ww4_sH6 ww6_sHc of ww7_sHg [Occ=Once] { __DEFAULT -> + GHC.Types.I# ww7_sHg + } + } + } + }}] +foo + = \ (w_sGZ :: (Int, Int)) (w1_sH0 :: Int) -> + case w_sGZ of { (ww1_sH3, ww2_sH8) -> + case ww1_sH3 of { GHC.Types.I# ww4_sH6 -> + case w1_sH0 of { GHC.Types.I# ww6_sHc -> + case Lib.$wfoo ww4_sH6 ww6_sHc of ww7_sHg { __DEFAULT -> + GHC.Types.I# ww7_sHg + } + } + } + } + + + ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -51,3 +51,6 @@ test('T17852', [ grep_errmsg(r'\\$wf ::') ], compile, ['-ddump-worker-wrapper - test('T16029', normal, makefile_test, []) test('T10069', [ grep_errmsg(r'(wc1).*Int#$') ], compile, ['-dppr-cols=200 -ddump-simpl']) + +# We just want to find the worker of foo in there: +test('T18122', [ grep_errmsg(r'wfoo') ], compile, ['-ddump-simpl']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/258e803175138ed5378c3c72a966f4e5f4fdb195 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/258e803175138ed5378c3c72a966f4e5f4fdb195 You're receiving 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 30 19:36:56 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 30 Apr 2020 15:36:56 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5eab28d85bace_6167c5ce1b081936ad@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 9e909251 by Sebastian Graf at 2020-04-30T21:36:48+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 6 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1997,7 +1997,7 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Remove ones that have too many worker variables small_pats = filterOut too_big non_dups - too_big (vars,_) = not (isWorkerSmallEnough (sc_dflags env) vars) + too_big (vars,args) = not (isWorkerSmallEnough (sc_dflags env) (length args) vars) -- We are about to construct w/w pair in 'spec_one'. -- Omit specialisation leading to high arity workers. -- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -162,7 +162,7 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if isWorkerSmallEnough dflags work_args + ; if isWorkerSmallEnough dflags (length demands) work_args && not (too_many_args_for_join_point wrap_args) && ((useful1 && not only_one_void_argument) || useful2) then return (Just (worker_args_dmds, length work_call_args, @@ -203,10 +203,13 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info = False -- See Note [Limit w/w arity] -isWorkerSmallEnough :: DynFlags -> [Var] -> Bool -isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags +isWorkerSmallEnough :: DynFlags -> Int -> [Var] -> Bool +isWorkerSmallEnough dflags old_n_args vars + = count isId vars <= max old_n_args (maxWorkerArgs dflags) -- We count only Free variables (isId) to skip Type, Kind -- variables which have no runtime representation. + -- Also if the function took 82 arguments before (old_n_args), it's fine if + -- it takes <= 82 arguments afterwards. {- Note [Always do CPR w/w] @@ -227,7 +230,8 @@ Guard against high worker arity as it generates a lot of stack traffic. A simplified example is #11565#comment:6 Current strategy is very simple: don't perform w/w transformation at all -if the result produces a wrapper with arity higher than -fmax-worker-args=. +if the result produces a wrapper with arity higher than -fmax-worker-args +and the number arguments before w/w. It is a bit all or nothing, consider ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -642,14 +642,15 @@ by saying ``-fno-wombat``. Sets the maximal number of iterations for the simplifier. .. ghc-flag:: -fmax-worker-args=⟨n⟩ - :shortdesc: *default: 10.* If a worker has that many arguments, none will - be unpacked anymore. + :shortdesc: *default: 10.* Maximum number of value arguments for a worker. :type: dynamic :category: :default: 10 - If a worker has that many arguments, none will be unpacked anymore. + A function will not be split into worker and wrapper if the number of + value arguments of the resulting worker exceeds both that of the original + function and this setting. .. ghc-flag:: -fno-opt-coercion :shortdesc: Turn off the coercion optimiser ===================================== testsuite/tests/stranal/should_compile/T18122.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -fforce-recomp -O2 -fmax-worker-args=1 #-} +module Lib where + +foo :: (Int, Int) -> Int -> Int +foo (x, y) z = x+z +{-# NOINLINE foo #-} ===================================== testsuite/tests/stranal/should_compile/T18122.stderr ===================================== @@ -0,0 +1,83 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 35, types: 27, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule3 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule3 = GHC.Types.TrNameS Lib.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule2 = "Lib"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule1 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule1 = GHC.Types.TrNameS Lib.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule :: GHC.Types.Module +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +Lib.$trModule = GHC.Types.Module Lib.$trModule3 Lib.$trModule1 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$wfoo [InlPrag=NOINLINE] + :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=2, Str=, Unf=OtherCon []] +Lib.$wfoo = (GHC.Prim.+#) + +-- RHS size: {terms: 18, types: 14, coercions: 0, joins: 0/0} +foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int +[GblId, + Arity=2, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (w_sGZ [Occ=Once!] :: (Int, Int)) + (w1_sH0 [Occ=Once!] :: Int) -> + case w_sGZ of { (ww1_sH3 [Occ=Once!], _ [Occ=Dead]) -> + case ww1_sH3 of { GHC.Types.I# ww4_sH6 [Occ=Once] -> + case w1_sH0 of { GHC.Types.I# ww6_sHc [Occ=Once] -> + case Lib.$wfoo ww4_sH6 ww6_sHc of ww7_sHg [Occ=Once] { __DEFAULT -> + GHC.Types.I# ww7_sHg + } + } + } + }}] +foo + = \ (w_sGZ :: (Int, Int)) (w1_sH0 :: Int) -> + case w_sGZ of { (ww1_sH3, ww2_sH8) -> + case ww1_sH3 of { GHC.Types.I# ww4_sH6 -> + case w1_sH0 of { GHC.Types.I# ww6_sHc -> + case Lib.$wfoo ww4_sH6 ww6_sHc of ww7_sHg { __DEFAULT -> + GHC.Types.I# ww7_sHg + } + } + } + } + + + ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -51,3 +51,6 @@ test('T17852', [ grep_errmsg(r'\\$wf ::') ], compile, ['-ddump-worker-wrapper - test('T16029', normal, makefile_test, []) test('T10069', [ grep_errmsg(r'(wc1).*Int#$') ], compile, ['-dppr-cols=200 -ddump-simpl']) + +# We just want to find the worker of foo in there: +test('T18122', [ grep_errmsg(r'wfoo') ], compile, ['-ddump-simpl']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e909251d187f1dadc7c1703eb5ebb3f3e737caf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e909251d187f1dadc7c1703eb5ebb3f3e737caf You're receiving 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 30 19:39:38 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 30 Apr 2020 15:39:38 -0400 Subject: [Git][ghc/ghc][wip/andreask/strict_dicts] 127 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5eab297a80e2_616711ab08a4819404a@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/andreask/strict_dicts at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.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 #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 9e909251 by Sebastian Graf at 2020-04-30T21:36:48+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - ed730d45 by Andreas Klebinger at 2020-04-30T21:37:58+02:00 Enable strict dicts by default. For now accept to see what hackage head will say. ------------------------- Metric Decrease: T12227 WWRec T12234 Metric Increase: T9630 T15164 T13056 ------------------------- - - - - - 0e24eaf4 by Andreas Klebinger at 2020-04-30T21:37:58+02:00 Apply SPJ's suggestions - - - - - 65fed487 by Sebastian Graf at 2020-04-30T21:38:20+02:00 Remove dead code - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/BlockId.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b9ff82fee1e600ca2c183725c97d2b6e1d59a668...65fed487fc1f99b1ee591c4038f7a92ac0959031 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b9ff82fee1e600ca2c183725c97d2b6e1d59a668...65fed487fc1f99b1ee591c4038f7a92ac0959031 You're receiving 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 30 21:27:46 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Thu, 30 Apr 2020 17:27:46 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] 14 commits: Document backpack fields in DynFlags Message-ID: <5eab42d25af0d_6167122e22ac8210760@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 3bf7e695 by Alan Zimmerman at 2020-04-30T22:27:10+01:00 Proof of Concept implementation of in-tree API Annotations This MR introduces a possible machinery to introduce API Annotations into the TTG extension points. It is intended to be a concrete example for discussion. It still needs to process comments. ---- Work in progress, adding more TTG extensions for annotations. And fixing ppr round-trip tests by being able to blank out in-tree annotations, as done with SrcSpans. This is needed for the case of class Foo a where for which current ppr does not print the "where". Rename AA to AddApiAnn and AA to AddAnn Add XConPatIn and XConPatOut Rebase ---- First pass at bringing in LocatedA for API anns in locations Treatment of ECP in parsing is provisional at this stage, leads to some horribly stuff in Parser.y and RdrHsSyn. It is an extensive but not invasive change. I think (AZ). Locally it reports some parsing tests using less memory. Add ApiAnns to the HsExpr data structure. rebase. Change HsMatchContext and HsStmtContext to use an id, not a GhcPass parameter. Add ApiAnns to Hs/Types Rebase Rebased 2020-03-25 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan ---- In-tree annotations: LHsDecl and LHsBind LocatedA ---- WIP on in-tree annotations ---- in-tree annotations: LHsType is now LocatedA ---- FunDeps is now also a HS data type ---- WIP. Added LocatedA to Pat, Expr, Decl And worked some more through Parser.y ---- LStmt now Located ---- Finished working through Parser.y, tests seem ok failures relate to annotations. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b15868a8f81ad7578cbf3d784345cf603239a130...3bf7e69555e7136d00f2dcf145d281916558e859 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b15868a8f81ad7578cbf3d784345cf603239a130...3bf7e69555e7136d00f2dcf145d281916558e859 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: